[vlc-devel] [PATCH 8/9] d3d11: add a shader to merge 2 fields into one surface
Steve Lhomme
robux4 at ycbcr.xyz
Mon Nov 16 13:44:19 CET 2020
---
modules/video_output/win32/d3d11_quad.c | 51 ++++++++++++++++++++++
modules/video_output/win32/d3d11_quad.h | 4 ++
modules/video_output/win32/d3d11_shaders.c | 47 ++++++++++++++++----
modules/video_output/win32/d3d11_shaders.h | 2 +
4 files changed, 95 insertions(+), 9 deletions(-)
diff --git a/modules/video_output/win32/d3d11_quad.c b/modules/video_output/win32/d3d11_quad.c
index b90ecacad8f..90b37fe8de5 100644
--- a/modules/video_output/win32/d3d11_quad.c
+++ b/modules/video_output/win32/d3d11_quad.c
@@ -90,6 +90,55 @@ void D3D11_RenderQuad(d3d11_device_t *d3d_dev, d3d_quad_t *quad, d3d_vertex_shad
}
}
+void D3D11_RenderMergeQuad(d3d11_device_t *d3d_dev, d3d_vertex_shader_t *vsshader, d3d_quad_t *quad,
+ ID3D11ShaderResourceView *field1Resources[D3D11_MAX_SHADER_VIEW],
+ ID3D11ShaderResourceView *field2Resources[D3D11_MAX_SHADER_VIEW],
+ d3d11_select_plane_t selectPlane, void *selectOpaque)
+{
+ UINT offset = 0;
+
+ /* Render the quad */
+ ID3D11DeviceContext_IASetPrimitiveTopology(d3d_dev->d3dcontext, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+
+ /* vertex shader */
+ ID3D11DeviceContext_IASetInputLayout(d3d_dev->d3dcontext, vsshader->layout);
+ ID3D11DeviceContext_IASetVertexBuffers(d3d_dev->d3dcontext, 0, 1, &quad->pVertexBuffer, &quad->vertexStride, &offset);
+ ID3D11DeviceContext_IASetIndexBuffer(d3d_dev->d3dcontext, quad->pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
+ if ( quad->viewpointShaderConstant )
+ ID3D11DeviceContext_VSSetConstantBuffers(d3d_dev->d3dcontext, 0, 1, &quad->viewpointShaderConstant);
+
+ ID3D11DeviceContext_VSSetShader(d3d_dev->d3dcontext, vsshader->shader, NULL, 0);
+
+ if (quad->SamplerStates[0])
+ ID3D11DeviceContext_PSSetSamplers(d3d_dev->d3dcontext, 0, 2, quad->SamplerStates);
+
+ /* pixel shader */
+ ID3D11DeviceContext_PSSetConstantBuffers(d3d_dev->d3dcontext, 0, ARRAY_SIZE(quad->pPixelShaderConstants), quad->pPixelShaderConstants);
+ assert(quad->resourceCount <= D3D11_MAX_SHADER_VIEW);
+
+ for (size_t i=0; i<D3D11_MAX_SHADER_VIEW; i++)
+ {
+ if (!quad->d3dpixelShader[i])
+ break;
+
+ if (unlikely(!selectPlane(selectOpaque, i)))
+ continue;
+
+ ID3D11ShaderResourceView *resources[8] = {
+ field1Resources[0], field1Resources[1], NULL, NULL,
+ field2Resources[0], field2Resources[1], NULL, NULL,
+ };
+
+ ID3D11DeviceContext_PSSetShaderResources(d3d_dev->d3dcontext, 0, 8, resources);
+
+ ID3D11DeviceContext_PSSetShader(d3d_dev->d3dcontext, quad->d3dpixelShader[i], NULL, 0);
+
+ ID3D11DeviceContext_RSSetViewports(d3d_dev->d3dcontext, 1, &quad->cropViewport[i]);
+
+ ID3D11DeviceContext_DrawIndexed(d3d_dev->d3dcontext, quad->indexCount, 0, 0);
+ }
+}
+
static bool AllocQuadVertices(vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_quad_t *quad, video_projection_mode_t projection)
{
HRESULT hr;
@@ -1010,6 +1059,8 @@ int D3D11_SetupQuad(vlc_object_t *o, d3d11_device_t *d3d_dev, const video_format
quad->shaderConstants.LuminanceScale = (float)displayFormat->luminance_peak / GetFormatLuminance(o, fmt);
+ quad->shaderConstants.Height = fmt->i_height;
+
/* pixel shader constant buffer */
quad->shaderConstants.Opacity = 1.0;
if (fmt->i_visible_width == fmt->i_width)
diff --git a/modules/video_output/win32/d3d11_quad.h b/modules/video_output/win32/d3d11_quad.h
index 8b7e231c384..50033af3800 100644
--- a/modules/video_output/win32/d3d11_quad.h
+++ b/modules/video_output/win32/d3d11_quad.h
@@ -50,6 +50,10 @@ typedef bool (*d3d11_select_plane_t)(void *opaque, size_t plane_index);
void D3D11_RenderQuad(d3d11_device_t *, d3d_quad_t *, d3d_vertex_shader_t *,
ID3D11ShaderResourceView *resourceViews[D3D11_MAX_SHADER_VIEW],
d3d11_select_plane_t selectPlane, void *selectOpaque);
+void D3D11_RenderMergeQuad(d3d11_device_t *, d3d_vertex_shader_t *, d3d_quad_t *,
+ ID3D11ShaderResourceView *field1Resources[D3D11_MAX_SHADER_VIEW],
+ ID3D11ShaderResourceView *field2Resources[D3D11_MAX_SHADER_VIEW],
+ d3d11_select_plane_t selectPlane, void *selectOpaque);
int D3D11_AllocateQuad(vlc_object_t *, d3d11_device_t *, video_projection_mode_t, d3d_quad_t *);
#define D3D11_AllocateQuad(a,b,c,d) D3D11_AllocateQuad(VLC_OBJECT(a),b,c,d)
diff --git a/modules/video_output/win32/d3d11_shaders.c b/modules/video_output/win32/d3d11_shaders.c
index 2e58ade8613..8a820d8159d 100644
--- a/modules/video_output/win32/d3d11_shaders.c
+++ b/modules/video_output/win32/d3d11_shaders.c
@@ -54,6 +54,8 @@ static const char* globPixelShaderDefault = "\
float BoundaryX;\n\
float BoundaryY;\n\
float LuminanceScale;\n\
+ float Height;\n\
+ float reserved[3];\n\
};\n\
cbuffer PS_COLOR_TRANSFORM : register(b1)\n\
{\n\
@@ -305,15 +307,42 @@ HRESULT (D3D11_CompilePixelShader)(vlc_object_t *o, const d3d11_shader_compiler_
{
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_P010:
- psz_sampler[0] =
- "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
- "sample.y = 0.0;\n"
- "sample.z = 0.0;\n"
- "sample.a = 1;";
- psz_sampler[1] =
- "sample.xy = shaderTexture[1].Sample(samplerState, coords).xy;\n"
- "sample.z = 0.0;\n"
- "sample.a = 1;";
+ switch (texture_count)
+ {
+ case 1:
+ psz_sampler[0] =
+ "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
+ "sample.y = 0.0;\n"
+ "sample.z = 0.0;\n"
+ "sample.a = 1;";
+ psz_sampler[1] =
+ "sample.xy = shaderTexture[1].Sample(samplerState, coords).xy;\n"
+ "sample.z = 0.0;\n"
+ "sample.a = 1;";
+ break;
+ case 2:
+ psz_sampler[0] =
+ "const int sample_line = coords.y * Height;\n"
+ "if ( ( sample_line % 2 ) == 0 )\n"
+ "sample.x = shaderTexture[0].Sample(samplerState, coords).x;\n"
+ "else\n"
+ "sample.x = shaderTexture[4].Sample(samplerState, coords).x;\n"
+ "sample.y = 0.0;\n"
+ "sample.z = 0.0;\n"
+ "sample.a = 1;";
+ psz_sampler[1] =
+ "const int sample_line = coords.y * Height;\n"
+ "if ( ( sample_line % 2 ) == 0 )\n"
+ "sample.xy = shaderTexture[1].Sample(samplerState, coords).xy;\n"
+ "else\n"
+ "sample.xy = shaderTexture[5].Sample(samplerState, coords).xy;\n"
+ "sample.z = 0.0;\n"
+ "sample.a = 1;";
+ break;
+ default:
+ vlc_assert_unreachable(); //unsupported
+ break;
+ }
break;
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
diff --git a/modules/video_output/win32/d3d11_shaders.h b/modules/video_output/win32/d3d11_shaders.h
index ff52633ddf3..212022d70f2 100644
--- a/modules/video_output/win32/d3d11_shaders.h
+++ b/modules/video_output/win32/d3d11_shaders.h
@@ -54,6 +54,8 @@ typedef struct {
FLOAT BoundaryX;
FLOAT BoundaryY;
FLOAT LuminanceScale;
+ FLOAT Height;
+ FLOAT reserved[3]; // unused for now
} PS_CONSTANT_BUFFER;
typedef struct {
--
2.26.2
More information about the vlc-devel
mailing list