[vlc-devel] [PATCH 3/6] direct3d11: add a Vertex Shader using a projection
Steve Lhomme
robux4 at videolabs.io
Tue Nov 22 11:59:41 CET 2016
The projection matrices are passed via a constant buffer.
---
modules/video_output/win32/common.h | 2 +
modules/video_output/win32/direct3d11.c | 84 ++++++++++++++++++++++++++++++++-
2 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/modules/video_output/win32/common.h b/modules/video_output/win32/common.h
index c499778..a8ce067 100644
--- a/modules/video_output/win32/common.h
+++ b/modules/video_output/win32/common.h
@@ -65,6 +65,7 @@ typedef struct
ID3D11VertexShader *d3dvertexShader;
ID3D11Buffer *pIndexBuffer;
UINT indexCount;
+ ID3D11Buffer *pVertexShaderConstants;
ID3D11Texture2D *pTexture;
ID3D11Buffer *pPixelShaderConstants;
ID3D11ShaderResourceView *d3dresViewY;
@@ -208,6 +209,7 @@ struct vout_display_sys_t
const char *d3dPxShader;
ID3D11VertexShader *flatVSShader;
+ ID3D11VertexShader *projectionVSShader;
// SPU
vlc_fourcc_t pSubpictureChromas[2];
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index e6ec5ad..07bb5a9 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -124,6 +124,16 @@ typedef struct {
FLOAT padding[3];
} PS_CONSTANT_BUFFER;
+typedef struct {
+ FLOAT RotX[16];
+ FLOAT RotY[16];
+ FLOAT RotZ[16];
+ FLOAT View[16];
+ FLOAT Projection[16];
+} VS_PROJECTION_CONST;
+
+#define SPHERE_RADIUS 1.f
+
#define RECTWidth(r) (int)((r).right - (r).left)
#define RECTHeight(r) (int)((r).bottom - (r).top)
@@ -185,8 +195,41 @@ static const char* globVertexShaderFlat = "\
\
VS_OUTPUT VS( VS_INPUT In )\
{\
+ return In;\
+ }\
+";
+
+static const char* globVertexShaderProjection = "\
+ cbuffer VS_PROJECTION_CONST : register(b0)\
+ {\
+ float4x4 RotX;\
+ float4x4 RotY;\
+ float4x4 RotZ;\
+ float4x4 View;\
+ float4x4 Projection;\
+ };\
+ struct VS_INPUT\
+ {\
+ float4 Position : POSITION;\
+ float2 Texture : TEXCOORD0;\
+ };\
+ \
+ struct VS_OUTPUT\
+ {\
+ float4 Position : SV_POSITION;\
+ float2 Texture : TEXCOORD0;\
+ };\
+ \
+ VS_OUTPUT VS( VS_INPUT In )\
+ {\
VS_OUTPUT Output;\
- Output.Position = In.Position;\
+ float4 pos = In.Position;\
+ pos = mul(RotY, pos);\
+ pos = mul(RotX, pos);\
+ pos = mul(RotZ, pos);\
+ pos = mul(View, pos);\
+ pos = mul(Projection, pos);\
+ Output.Position = pos;\
Output.Texture = In.Texture;\
return Output;\
}\
@@ -950,6 +993,8 @@ static void DisplayD3DPicture(vout_display_sys_t *sys, d3d_quad_t *quad)
/* vertex shader */
ID3D11DeviceContext_IASetVertexBuffers(sys->d3dcontext, 0, 1, &quad->pVertexBuffer, &stride, &offset);
ID3D11DeviceContext_IASetIndexBuffer(sys->d3dcontext, quad->pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
+ if ( quad->pVertexShaderConstants )
+ ID3D11DeviceContext_VSSetConstantBuffers(sys->d3dcontext, 0, 1, &quad->pVertexShaderConstants);
ID3D11DeviceContext_VSSetShader(sys->d3dcontext, quad->d3dvertexShader, NULL, 0);
@@ -1557,6 +1602,24 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
ID3D11DeviceContext_IASetInputLayout(sys->d3dcontext, pVertexLayout);
ID3D11InputLayout_Release(pVertexLayout);
+ hr = D3DCompile(globVertexShaderProjection, strlen(globVertexShaderProjection),
+ NULL, NULL, NULL, "VS", "vs_4_0_level_9_1", 0, 0, &pVSBlob, NULL);
+
+ if( FAILED(hr)) {
+ msg_Err(vd, "The projection Vertex Shader is invalid. (hr=0x%lX)", hr);
+ return VLC_EGENERIC;
+ }
+
+ hr = ID3D11Device_CreateVertexShader(sys->d3ddevice, (void *)ID3D10Blob_GetBufferPointer(pVSBlob),
+ ID3D10Blob_GetBufferSize(pVSBlob), NULL, &sys->projectionVSShader);
+
+ if(FAILED(hr)) {
+ ID3D11Device_Release(pVSBlob);
+ msg_Err(vd, "Failed to create the projection vertex shader. (hr=0x%lX)", hr);
+ return VLC_EGENERIC;
+ }
+ ID3D10Blob_Release(pVSBlob);
+
ID3D11DeviceContext_IASetPrimitiveTopology(sys->d3dcontext, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3DBlob* pPSBlob = NULL;
@@ -1897,6 +1960,15 @@ static int AllocQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *
goto error;
}
+ /* vertex shader constant buffer */
+ constantDesc.ByteWidth = sizeof(VS_PROJECTION_CONST);
+ static_assert((sizeof(VS_PROJECTION_CONST)%16)==0,"Constant buffers require 16-byte alignment");
+ hr = ID3D11Device_CreateBuffer(sys->d3ddevice, &constantDesc, NULL, &quad->pVertexShaderConstants);
+ if(FAILED(hr)) {
+ msg_Err(vd, "Could not create the vertex shader constant buffer. (hr=0x%lX)", hr);
+ goto error;
+ }
+
D3D11_TEXTURE2D_DESC texDesc;
memset(&texDesc, 0, sizeof(texDesc));
texDesc.Width = b_visible ? fmt->i_visible_width : fmt->i_width;
@@ -2003,6 +2075,11 @@ static void ReleaseQuad(d3d_quad_t *quad)
ID3D11Buffer_Release(quad->pIndexBuffer);
quad->pIndexBuffer = NULL;
}
+ if (quad->pVertexShaderConstants)
+ {
+ ID3D11Buffer_Release(quad->pVertexShaderConstants);
+ quad->pVertexShaderConstants = NULL;
+ }
if (quad->pTexture)
{
ID3D11Texture2D_Release(quad->pTexture);
@@ -2042,6 +2119,11 @@ static void Direct3D11DestroyResources(vout_display_t *vd)
ID3D11VertexShader_Release(sys->flatVSShader);
sys->flatVSShader = NULL;
}
+ if (sys->projectionVSShader)
+ {
+ ID3D11VertexShader_Release(sys->projectionVSShader);
+ sys->projectionVSShader = NULL;
+ }
if (sys->d3drenderTargetView)
{
ID3D11RenderTargetView_Release(sys->d3drenderTargetView);
--
2.10.1
More information about the vlc-devel
mailing list