[vlc-devel] [PATCH] direct3d11: allow custom shader per pixel format
Steve Lhomme
robux4 at videolabs.io
Wed Mar 25 17:51:42 CET 2015
---
modules/video_output/msw/common.h | 1 +
modules/video_output/msw/direct3d11.c | 157 ++++++++++++++++++----------------
2 files changed, 82 insertions(+), 76 deletions(-)
diff --git a/modules/video_output/msw/common.h b/modules/video_output/msw/common.h
index 2aeeba7..20ca328 100644
--- a/modules/video_output/msw/common.h
+++ b/modules/video_output/msw/common.h
@@ -177,6 +177,7 @@ struct vout_display_sys_t
DXGI_FORMAT d3dFormatY;
DXGI_FORMAT d3dFormatUV;
vlc_fourcc_t vlcFormat;
+ const char *d3dPxShader;
#endif
#ifdef MODULE_NAME_IS_direct3d9
diff --git a/modules/video_output/msw/direct3d11.c b/modules/video_output/msw/direct3d11.c
index 09334fb..333fa60 100644
--- a/modules/video_output/msw/direct3d11.c
+++ b/modules/video_output/msw/direct3d11.c
@@ -63,35 +63,6 @@ vlc_module_begin ()
set_callbacks(Open, Close)
vlc_module_end ()
-typedef struct
-{
- const char *name;
- DXGI_FORMAT formatTexture;
- vlc_fourcc_t fourcc;
- DXGI_FORMAT formatY;
- DXGI_FORMAT formatUV;
-} d3d_format_t;
-
-static const d3d_format_t d3d_formats[] = {
- { "NV12", DXGI_FORMAT_NV12, VLC_CODEC_NV12, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
-#ifdef BROKEN_PIXEL
- { "YUY2", DXGI_FORMAT_YUY2, VLC_CODEC_I422, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
- { "AYUV", DXGI_FORMAT_AYUV, VLC_CODEC_YUVA, DXGI_FORMAT_R8G8B8A8_UNORM, 0 },
- { "Y416", DXGI_FORMAT_Y416, VLC_CODEC_I444_16L, DXGI_FORMAT_R16G16B16A16_UINT, 0 },
-#endif
-#ifdef UNTESTED
- { "P010", DXGI_FORMAT_P010, VLC_CODEC_I420_10L, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM },
- { "Y210", DXGI_FORMAT_Y210, VLC_CODEC_I422_10L, DXGI_FORMAT_R16G16B16A16_UNORM, 0 },
- { "Y410", DXGI_FORMAT_Y410, VLC_CODEC_I444_10L, DXGI_FORMAT_R10G10B10A2_UNORM, 0 },
- { "NV11", DXGI_FORMAT_NV11, VLC_CODEC_I411, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM },
-#endif
- { "R8G8B8X8", DXGI_FORMAT_B8G8R8X8_UNORM, VLC_CODEC_RGB32, DXGI_FORMAT_B8G8R8X8_UNORM, 0 },
- { "B8G8R8A8", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_BGRA, DXGI_FORMAT_B8G8R8A8_UNORM, 0 },
- { "B5G6R5", DXGI_FORMAT_B5G6R5_UNORM, VLC_CODEC_RGB16, DXGI_FORMAT_B5G6R5_UNORM, 0 },
-
- { NULL, 0, 0, 0, 0}
-};
-
static const vlc_fourcc_t d3d_subpicture_chromas[] = {
VLC_CODEC_RGBA,
0
@@ -152,7 +123,7 @@ static const char* globVertexShaderDefault = "\
}\
";
-static const char* globPixelShaderDefault = "\
+#define globPixelShaderDefault "\
Texture2D shaderTexture;\
SamplerState SampleType;\
\
@@ -166,9 +137,9 @@ static const char* globPixelShaderDefault = "\
{\
return shaderTexture.Sample(SampleType, In.Texture);\
}\
-";
+"
-static const char* globPixelShaderBiplanarYUV2RGB = "\
+#define globPixelShaderBiplanarYUV2RGB "\
Texture2D shaderTextureY;\
Texture2D shaderTextureUV;\
SamplerState SampleType;\
@@ -194,8 +165,37 @@ static const char* globPixelShaderBiplanarYUV2RGB = "\
rgba.w = 1.0;\
return rgba;\
}\
-";
+"
+
+typedef struct
+{
+ const char *name;
+ DXGI_FORMAT formatTexture;
+ vlc_fourcc_t fourcc;
+ DXGI_FORMAT formatY;
+ DXGI_FORMAT formatUV;
+ const char *px_shader;
+} d3d_format_t;
+
+static const d3d_format_t d3d_formats[] = {
+ { "NV12", DXGI_FORMAT_NV12, VLC_CODEC_NV12, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM, globPixelShaderBiplanarYUV2RGB },
+#ifdef BROKEN_PIXEL
+ { "YUY2", DXGI_FORMAT_YUY2, VLC_CODEC_I422, DXGI_FORMAT_R8G8B8A8_UNORM, 0, globPixelShaderDefault },
+ { "AYUV", DXGI_FORMAT_AYUV, VLC_CODEC_YUVA, DXGI_FORMAT_R8G8B8A8_UNORM, 0, globPixelShaderDefault },
+ { "Y416", DXGI_FORMAT_Y416, VLC_CODEC_I444_16L, DXGI_FORMAT_R16G16B16A16_UINT, 0, globPixelShaderDefault },
+#endif
+#ifdef UNTESTED
+ { "P010", DXGI_FORMAT_P010, VLC_CODEC_I420_10L, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, globPixelShaderBiplanarYUV2RGB },
+ { "Y210", DXGI_FORMAT_Y210, VLC_CODEC_I422_10L, DXGI_FORMAT_R16G16B16A16_UNORM, 0, globPixelShaderDefault },
+ { "Y410", DXGI_FORMAT_Y410, VLC_CODEC_I444_10L, DXGI_FORMAT_R10G10B10A2_UNORM, 0, globPixelShaderDefault },
+ { "NV11", DXGI_FORMAT_NV11, VLC_CODEC_I411, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM, globPixelShaderBiplanarYUV2RGB },
+#endif
+ { "R8G8B8X8", DXGI_FORMAT_B8G8R8X8_UNORM, VLC_CODEC_RGB32, DXGI_FORMAT_B8G8R8X8_UNORM, 0, globPixelShaderDefault },
+ { "B8G8R8A8", DXGI_FORMAT_B8G8R8A8_UNORM, VLC_CODEC_BGRA, DXGI_FORMAT_B8G8R8A8_UNORM, 0, globPixelShaderDefault },
+ { "B5G6R5", DXGI_FORMAT_B5G6R5_UNORM, VLC_CODEC_RGB16, DXGI_FORMAT_B5G6R5_UNORM, 0, globPixelShaderDefault },
+ { NULL, 0, 0, 0, 0, NULL}
+};
static int Open(vlc_object_t *object)
{
@@ -356,11 +356,14 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
/* Render the quad */
ID3D11DeviceContext_VSSetShader(sys->d3dcontext, sys->d3dvertexShader, NULL, 0);
- ID3D11DeviceContext_PSSetShader(sys->d3dcontext, sys->d3dpixelShader, NULL, 0);
- ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 0, 1, &sys->d3dresViewY);
+ if( sys->d3dPxShader )
+ {
+ ID3D11DeviceContext_PSSetShader(sys->d3dcontext, sys->d3dpixelShader, NULL, 0);
+ ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 0, 1, &sys->d3dresViewY);
- if( sys->d3dFormatUV )
- ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 1, 1, &sys->d3dresViewUV);
+ if( sys->d3dFormatUV )
+ ID3D11DeviceContext_PSSetShaderResources(sys->d3dcontext, 1, 1, &sys->d3dresViewUV);
+ }
ID3D11DeviceContext_PSSetSamplers(sys->d3dcontext, 0, 1, &sys->d3dsampState);
ID3D11DeviceContext_DrawIndexed(sys->d3dcontext, 6, 0, 0);
@@ -593,10 +596,11 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
( i_formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D ))
{
msg_Dbg(vd, "Using pixel format %s", d3d_formats[i].name );
- sys->d3dFormatTex = d3d_formats[i].formatTexture;
- sys->vlcFormat = d3d_formats[i].fourcc;
- sys->d3dFormatY = d3d_formats[i].formatY;
- sys->d3dFormatUV = d3d_formats[i].formatUV;
+ sys->d3dFormatTex = d3d_formats[i].formatTexture;
+ sys->vlcFormat = d3d_formats[i].fourcc;
+ sys->d3dFormatY = d3d_formats[i].formatY;
+ sys->d3dFormatUV = d3d_formats[i].formatUV;
+ sys->d3dPxShader = d3d_formats[i].px_shader;
break;
}
}
@@ -744,30 +748,28 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
ID3D11DeviceContext_IASetInputLayout(sys->d3dcontext, pVertexLayout);
- ID3DBlob* pPSBlob = NULL;
+ if( sys->d3dPxShader )
+ {
+ ID3DBlob* pPSBlob = NULL;
- /* TODO : Match the version to the D3D_FEATURE_LEVEL */
- if( sys->d3dFormatUV )
- hr = D3DCompile(globPixelShaderBiplanarYUV2RGB, strlen(globPixelShaderBiplanarYUV2RGB),
+ /* TODO : Match the version to the D3D_FEATURE_LEVEL */
+ hr = D3DCompile(sys->d3dPxShader, strlen(sys->d3dPxShader),
NULL, NULL, NULL, "PS", "ps_4_0_level_9_1", 0, 0, &pPSBlob, NULL);
- else
- hr = D3DCompile(globPixelShaderDefault, strlen(globPixelShaderDefault),
- NULL, NULL, NULL, "PS", "ps_4_0_level_9_1", 0, 0, &pPSBlob, NULL);
-
- if( FAILED(hr)) {
- msg_Err(vd, "The Pixel Shader is invalid.");
- return VLC_EGENERIC;
- }
+ if( FAILED(hr)) {
+ msg_Err(vd, "The Pixel Shader is invalid. (hr=0x%lX)", hr );
+ return VLC_EGENERIC;
+ }
- hr = ID3D11Device_CreatePixelShader(sys->d3ddevice, (void *)ID3D10Blob_GetBufferPointer(pPSBlob),
- ID3D10Blob_GetBufferSize(pPSBlob), NULL, &sys->d3dpixelShader);
+ hr = ID3D11Device_CreatePixelShader(sys->d3ddevice, (void *)ID3D10Blob_GetBufferPointer(pPSBlob),
+ ID3D10Blob_GetBufferSize(pPSBlob), NULL, &sys->d3dpixelShader);
- ID3D10Blob_Release(pPSBlob);
+ ID3D10Blob_Release(pPSBlob);
- if(FAILED(hr)) {
- msg_Err(vd, "Failed to create the pixel shader.");
- return VLC_EGENERIC;
+ if(FAILED(hr)) {
+ msg_Err(vd, "Failed to create the pixel shader.");
+ return VLC_EGENERIC;
+ }
}
float vertices[] = {
@@ -844,28 +846,31 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
return VLC_EGENERIC;
}
- D3D11_SHADER_RESOURCE_VIEW_DESC resviewDesc;
- memset(&resviewDesc, 0, sizeof(resviewDesc));
- resviewDesc.Format = sys->d3dFormatY;
- resviewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
- resviewDesc.Texture2D.MipLevels = texDesc.MipLevels;
-
- hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewY);
- if (FAILED(hr)) {
- if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
- msg_Err(vd, "Could not Create the Y D3d11 Texture ResourceView. (hr=0x%lX)", hr);
- return VLC_EGENERIC;
- }
-
- if( sys->d3dFormatUV )
+ if( sys->d3dPxShader )
{
- resviewDesc.Format = sys->d3dFormatUV;
- hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewUV);
+ D3D11_SHADER_RESOURCE_VIEW_DESC resviewDesc;
+ memset(&resviewDesc, 0, sizeof(resviewDesc));
+ resviewDesc.Format = sys->d3dFormatY;
+ resviewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ resviewDesc.Texture2D.MipLevels = texDesc.MipLevels;
+
+ hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewY);
if (FAILED(hr)) {
if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
- msg_Err(vd, "Could not Create the UV D3d11 Texture ResourceView. (hr=0x%lX)", hr);
+ msg_Err(vd, "Could not Create the Y D3d11 Texture ResourceView. (hr=0x%lX)", hr);
return VLC_EGENERIC;
}
+
+ if( sys->d3dFormatUV )
+ {
+ resviewDesc.Format = sys->d3dFormatUV;
+ hr = ID3D11Device_CreateShaderResourceView(sys->d3ddevice, (ID3D11Resource *)sys->d3dtexture, &resviewDesc, &sys->d3dresViewUV);
+ if (FAILED(hr)) {
+ if(sys->d3dtexture) ID3D11Texture2D_Release(sys->d3dtexture);
+ msg_Err(vd, "Could not Create the UV D3d11 Texture ResourceView. (hr=0x%lX)", hr);
+ return VLC_EGENERIC;
+ }
+ }
}
D3D11_SAMPLER_DESC sampDesc;
--
2.3.0
More information about the vlc-devel
mailing list