| 
					
				 | 
			
			
				@@ -258,6 +258,17 @@ void gs_device::InitDevice(uint32_t adapterIdx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (FAILED(hr)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		throw UnsupportedHWError("Failed to create device", hr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ComQIPtr<ID3D11Device1> d3d11_1(device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!!d3d11_1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		D3D11_FEATURE_DATA_D3D11_OPTIONS opts = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		hr = d3d11_1->CheckFeatureSupport( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				D3D11_FEATURE_D3D11_OPTIONS, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				&opts, sizeof(opts)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (SUCCEEDED(hr)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			nv12Supported = !!opts.ExtendedResourceSharing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	blog(LOG_INFO, "D3D11 loaded successfully, feature level used: %u", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			(unsigned int)levelUsed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1315,7 +1326,7 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			throw "Source texture must be a 2D texture"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (!dst) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			throw "Destination surface is NULL"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (dst->format != src->format) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (dst->format != GS_UNKNOWN && dst->format != src->format) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			throw "Source and destination formats do not match"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if (dst->width  != src2d->width || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		    dst->height != src2d->height) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2054,6 +2065,11 @@ extern "C" EXPORT bool device_shared_texture_available(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+extern "C" EXPORT bool device_nv12_available(gs_device_t *device) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return device->nv12Supported; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		uint32_t width, uint32_t height) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2174,3 +2190,53 @@ extern "C" EXPORT int device_texture_release_sync(gs_texture_t *tex, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	HRESULT hr = keyedMutex->ReleaseSync(key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return hr == S_OK ? 0 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+extern "C" EXPORT bool device_texture_create_nv12(gs_device_t *device, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gs_texture_t **p_tex_y, gs_texture_t **p_tex_uv, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		uint32_t width, uint32_t height, uint32_t flags) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!device->nv12Supported) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*p_tex_y = nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*p_tex_uv = nullptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gs_texture_2d *tex_y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gs_texture_2d *tex_uv; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		tex_y = new gs_texture_2d(device, width, height, GS_R8, 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				nullptr, flags, GS_TEXTURE_2D, false, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		tex_uv = new gs_texture_2d(device, tex_y->texture, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} catch (HRError error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		blog(LOG_ERROR, "gs_texture_create_nv12 (D3D11): %s (%08lX)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				error.str, error.hr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		LogD3D11ErrorDetails(error, device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} catch (const char *error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		blog(LOG_ERROR, "gs_texture_create_nv12 (D3D11): %s", error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*p_tex_y = tex_y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	*p_tex_uv = tex_uv; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+extern "C" EXPORT gs_stagesurf_t *device_stagesurface_create_nv12( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gs_device_t *device, uint32_t width, uint32_t height) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gs_stage_surface *surf = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		surf = new gs_stage_surface(device, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} catch (HRError error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		blog(LOG_ERROR, "device_stagesurface_create (D3D11): %s " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		                "(%08lX)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				error.str, error.hr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		LogD3D11ErrorDetails(error, device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return surf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |