[vlc-commits] Revert "direct3d11: sample only the visible area of the texture"

Steve Lhomme git at videolan.org
Tue Sep 1 09:23:16 CEST 2020


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Tue Sep  1 09:20:25 2020 +0200| [3a90a2fb122c3d48087703b72a3a37de1cc73841] | committer: Steve Lhomme

Revert "direct3d11: sample only the visible area of the texture"

This reverts commit 968e3788f56b5b6ad6cfdd12b6bbcf87e5853c7c.

This adds extra processing for each pixel where we can do without.
Also it wasn't updated when the crop values change.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3a90a2fb122c3d48087703b72a3a37de1cc73841
---

 modules/video_output/win32/d3d11_quad.c    | 121 +++++++++++++++++++++++------
 modules/video_output/win32/d3d11_quad.h    |   2 +-
 modules/video_output/win32/d3d11_shaders.c |   4 +-
 modules/video_output/win32/d3d11_shaders.h |   3 +-
 modules/video_output/win32/direct3d11.c    |  62 +++++++++------
 5 files changed, 140 insertions(+), 52 deletions(-)

diff --git a/modules/video_output/win32/d3d11_quad.c b/modules/video_output/win32/d3d11_quad.c
index ecfbf99b39..f5d2bc285b 100644
--- a/modules/video_output/win32/d3d11_quad.c
+++ b/modules/video_output/win32/d3d11_quad.c
@@ -265,14 +265,89 @@ static void orientationVertexOrder(video_orientation_t orientation, int vertex_o
     }
 }
 
-static void SetupQuadFlat(d3d_vertex_t *dst_data, const POINT *output,
+static void SetupQuadFlat(d3d_vertex_t *dst_data, const RECT *output,
+                          const d3d_quad_t *quad,
                           WORD *triangle_pos, video_orientation_t orientation)
 {
-    unsigned int src_width = output->x;
-    unsigned int src_height = output->y;
+    unsigned int src_width = quad->i_width;
+    unsigned int src_height = quad->i_height;
     float MidX,MidY;
 
-    float top = 1, bottom = -1, left = -1, right = 1;
+    float top, bottom, left, right;
+    /* find the middle of the visible part of the texture, it will be a 0,0
+     * the rest of the visible area must correspond to -1,1 */
+    switch (orientation)
+    {
+    case ORIENT_ROTATED_90: /* 90° anti clockwise */
+        /* right/top aligned */
+        MidY = (output->left + output->right) / 2.f;
+        MidX = (output->top + output->bottom) / 2.f;
+        top    =  MidY / (MidY - output->top);
+        bottom = -(src_height - MidX) / (MidX - output->top);
+        left   =  (MidX - src_height) / (MidX - output->left);
+        right  =                 MidX / (MidX - (src_width - output->right));
+        break;
+    case ORIENT_ROTATED_180: /* 180° */
+        /* right/top aligned */
+        MidY = (output->top + output->bottom) / 2.f;
+        MidX = (output->left + output->right) / 2.f;
+        top    =  (src_height - MidY) / (output->bottom - MidY);
+        bottom = -MidY / (MidY - output->top);
+        left   = -MidX / (MidX - output->left);
+        right  =  (src_width  - MidX) / (output->right - MidX);
+        break;
+    case ORIENT_ROTATED_270: /* 90° clockwise */
+        /* right/top aligned */
+        MidY = (output->left + output->right) / 2.f;
+        MidX = (output->top + output->bottom) / 2.f;
+        top    =  (src_width  - MidX) / (output->right - MidX);
+        bottom = -MidY / (MidY - output->top);
+        left   = -MidX / (MidX - output->left);
+        right  =  (src_height - MidY) / (output->bottom - MidY);
+        break;
+    case ORIENT_ANTI_TRANSPOSED:
+        MidY = (output->left + output->right) / 2.f;
+        MidX = (output->top + output->bottom) / 2.f;
+        top    =  (src_width  - MidX) / (output->right - MidX);
+        bottom = -MidY / (MidY - output->top);
+        left   = -(src_height - MidY) / (output->bottom - MidY);
+        right  =  MidX / (MidX - output->left);
+        break;
+    case ORIENT_TRANSPOSED:
+        MidY = (output->left + output->right) / 2.f;
+        MidX = (output->top + output->bottom) / 2.f;
+        top    =  (src_width  - MidX) / (output->right - MidX);
+        bottom = -MidY / (MidY - output->top);
+        left   = -MidX / (MidX - output->left);
+        right  =  (src_height - MidY) / (output->bottom - MidY);
+        break;
+    case ORIENT_VFLIPPED:
+        MidY = (output->top + output->bottom) / 2.f;
+        MidX = (output->left + output->right) / 2.f;
+        top    =  (src_height - MidY) / (output->bottom - MidY);
+        bottom = -MidY / (MidY - output->top);
+        left   = -MidX / (MidX - output->left);
+        right  =  (src_width  - MidX) / (output->right - MidX);
+        break;
+    case ORIENT_HFLIPPED:
+        MidY = (output->top + output->bottom) / 2.f;
+        MidX = (output->left + output->right) / 2.f;
+        top    =  MidY / (MidY - output->top);
+        bottom = -(src_height - MidY) / (output->bottom - MidY);
+        left   = -(src_width  - MidX) / (output->right - MidX);
+        right  =  MidX / (MidX - output->left);
+        break;
+    case ORIENT_NORMAL:
+    default:
+        /* left/top aligned */
+        MidY = (output->top + output->bottom) / 2.f;
+        MidX = (output->left + output->right) / 2.f;
+        top    =  MidY / (MidY - output->top);
+        bottom = -(src_height - MidY) / (output->bottom - MidY);
+        left   = -MidX / (MidX - output->left);
+        right  =  (src_width  - MidX) / (output->right - MidX);
+        break;
+    }
 
     const float vertices_coords[4][2] = {
         { left,  bottom },
@@ -334,8 +409,11 @@ static void SetupQuadFlat(d3d_vertex_t *dst_data, const POINT *output,
     }
 }
 
-static void SetupQuadSphere(d3d_vertex_t *dst_data, WORD *triangle_pos)
+static void SetupQuadSphere(d3d_vertex_t *dst_data, const RECT *output,
+                            const d3d_quad_t *quad, WORD *triangle_pos)
 {
+    const float scaleX = (float)(RECTWidth(*output))  / quad->i_width;
+    const float scaleY = (float)(RECTHeight(*output)) / quad->i_height;
     for (unsigned lat = 0; lat <= nbLatBands; lat++) {
         float theta = lat * (float) M_PI / nbLatBands;
         float sinTheta, cosTheta;
@@ -357,8 +435,8 @@ static void SetupQuadSphere(d3d_vertex_t *dst_data, WORD *triangle_pos)
             dst_data[off1].position.y = SPHERE_RADIUS * y;
             dst_data[off1].position.z = SPHERE_RADIUS * z;
 
-            dst_data[off1].texture.x = lon / (float) nbLonBands;
-            dst_data[off1].texture.y = lat / (float) nbLatBands;
+            dst_data[off1].texture.x = scaleX * lon / (float) nbLonBands; // 0(left) to 1(right)
+            dst_data[off1].texture.y = scaleY * lat / (float) nbLatBands; // 0(top) to 1 (bottom)
         }
     }
 
@@ -381,7 +459,8 @@ static void SetupQuadSphere(d3d_vertex_t *dst_data, WORD *triangle_pos)
 }
 
 
-static void SetupQuadCube(d3d_vertex_t *dst_data, WORD *triangle_pos)
+static void SetupQuadCube(d3d_vertex_t *dst_data, const RECT *output,
+                          const d3d_quad_t *quad, WORD *triangle_pos)
 {
 #define CUBEFACE(swap, value) \
     swap(value, -1.f,  1.f), \
@@ -407,8 +486,11 @@ static void SetupQuadCube(d3d_vertex_t *dst_data, WORD *triangle_pos)
 #undef Z_FACE
 #undef CUBEFACE
 
-    const float col[] = {0.f, 1.f / 3, 2.f / 3, 1.f};
-    const float row[] = {0.f, 1.f / 2, 1.f};
+    const float scaleX = (float)(output->right - output->left) / quad->i_width;
+    const float scaleY = (float)(output->bottom - output->top) / quad->i_height;
+
+    const float col[] = {0.f, scaleX / 3, scaleX * 2 / 3, scaleX};
+    const float row[] = {0.f, scaleY / 2, scaleY};
 
     const float tex[] = {
         col[1], row[1], // front
@@ -468,7 +550,7 @@ static void SetupQuadCube(d3d_vertex_t *dst_data, WORD *triangle_pos)
 
 #undef D3D11_UpdateQuadPosition
 bool D3D11_UpdateQuadPosition( vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_quad_t *quad,
-                                const POINT *output, video_orientation_t orientation )
+                                const RECT *output, video_orientation_t orientation )
 {
     bool result = true;
     HRESULT hr;
@@ -497,13 +579,13 @@ bool D3D11_UpdateQuadPosition( vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_qua
     switch (quad->projection)
     {
     case PROJECTION_MODE_RECTANGULAR:
-        SetupQuadFlat(dst_data, output, mappedResource.pData, orientation);
+        SetupQuadFlat(dst_data, output, quad, mappedResource.pData, orientation);
         break;
     case PROJECTION_MODE_EQUIRECTANGULAR:
-        SetupQuadSphere(dst_data, mappedResource.pData);
+        SetupQuadSphere(dst_data, output, quad, mappedResource.pData);
         break;
     case PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD:
-        SetupQuadCube(dst_data, mappedResource.pData);
+        SetupQuadCube(dst_data, output, quad, mappedResource.pData);
         break;
     default:
         msg_Warn(o, "Projection mode %d not handled", quad->projection);
@@ -900,17 +982,6 @@ int D3D11_SetupQuad(vlc_object_t *o, d3d11_device_t *d3d_dev, const video_format
     };
 
     PS_COLOR_TRANSFORM colorspace;
-    memcpy(colorspace.SourceCrop, IDENTITY_4X4, sizeof(colorspace.SourceCrop));
-    float scale_w = (float)fmt->i_visible_width  / fmt->i_width;
-    float scale_h = (float)fmt->i_visible_height / fmt->i_height;
-    float left   = scale_w * fmt->i_x_offset;
-    float top    = scale_h * fmt->i_y_offset;
-
-    colorspace.SourceCrop[0*4 + 0] = scale_h;
-    colorspace.SourceCrop[1*4 + 1] = scale_w;
-
-    colorspace.SourceCrop[0*4 + 3] = left / fmt->i_visible_width;
-    colorspace.SourceCrop[1*4 + 3] = top  / fmt->i_visible_height;
 
     memcpy(colorspace.WhitePoint, IDENTITY_4X4, sizeof(colorspace.WhitePoint));
 
diff --git a/modules/video_output/win32/d3d11_quad.h b/modules/video_output/win32/d3d11_quad.h
index 662af7fead..db3926befe 100644
--- a/modules/video_output/win32/d3d11_quad.h
+++ b/modules/video_output/win32/d3d11_quad.h
@@ -61,7 +61,7 @@ int D3D11_SetupQuad(vlc_object_t *, d3d11_device_t *, const video_format_t *, d3
 #define D3D11_SetupQuad(a,b,c,d,e)  D3D11_SetupQuad(VLC_OBJECT(a),b,c,d,e)
 
 bool D3D11_UpdateQuadPosition( vlc_object_t *, d3d11_device_t *, d3d_quad_t *,
-                               const POINT *output, video_orientation_t );
+                               const RECT *output, video_orientation_t );
 #define D3D11_UpdateQuadPosition(a,b,c,d,e)  D3D11_UpdateQuadPosition(VLC_OBJECT(a),b,c,d,e)
 
 void D3D11_UpdateViewport(d3d_quad_t *, const RECT *, const d3d_format_t *display);
diff --git a/modules/video_output/win32/d3d11_shaders.c b/modules/video_output/win32/d3d11_shaders.c
index e1df979692..8f718b933c 100644
--- a/modules/video_output/win32/d3d11_shaders.c
+++ b/modules/video_output/win32/d3d11_shaders.c
@@ -61,7 +61,6 @@ static const char* globPixelShaderDefault = "\
   };\n\
   cbuffer PS_COLOR_TRANSFORM : register(b1)\n\
   {\n\
-    float4x4 SourceCrop;\n\
     float4x4 WhitePoint;\n\
     float4x4 Colorspace;\n\
     float4x4 Primaries;\n\
@@ -118,8 +117,7 @@ static const char* globPixelShaderDefault = "\
       %s;\n\
   }\n\
   \n\
-  inline float4 sampleTexture(SamplerState samplerState, float3 raw_coords) {\n\
-      float3 coords = mul(float4(raw_coords.xyz, 1), SourceCrop).xyz;\n\
+  inline float4 sampleTexture(SamplerState samplerState, float3 coords) {\n\
       float4 sample;\n\
       %s /* sampling routine in sample */\n\
       return sample;\n\
diff --git a/modules/video_output/win32/d3d11_shaders.h b/modules/video_output/win32/d3d11_shaders.h
index f3e47d48cc..7712c3eff3 100644
--- a/modules/video_output/win32/d3d11_shaders.h
+++ b/modules/video_output/win32/d3d11_shaders.h
@@ -57,7 +57,6 @@ typedef struct {
 } PS_CONSTANT_BUFFER;
 
 typedef struct {
-    FLOAT SourceCrop[4*4];
     FLOAT WhitePoint[4*4];
     FLOAT Colorspace[4*4];
     FLOAT Primaries[4*4];
@@ -95,6 +94,8 @@ typedef struct
     ID3D11PixelShader         *d3dpixelShader[D3D11_MAX_SHADER_VIEW];
     ID3D11SamplerState        *d3dsampState[2];
     D3D11_VIEWPORT            cropViewport[D3D11_MAX_SHADER_VIEW];
+    unsigned int              i_width;
+    unsigned int              i_height;
     video_projection_mode_t   projection;
 
     PS_CONSTANT_BUFFER        shaderConstants;
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index b0f2e5ad0d..b6881ecc8b 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -277,9 +277,11 @@ static void UpdateSize(vout_display_t *vd)
 
     D3D11_UpdateViewport( &sys->picQuad, &rect_dst, sys->display.pixelFormat );
 
-    POINT source_rect = {
-        .x = vd->source.i_visible_width,
-        .y = vd->source.i_visible_height,
+    RECT source_rect = {
+        .left   = vd->fmt.i_x_offset,
+        .right  = vd->fmt.i_x_offset + vd->fmt.i_visible_width,
+        .top    = vd->fmt.i_y_offset,
+        .bottom = vd->fmt.i_y_offset + vd->fmt.i_visible_height,
     };
     d3d11_device_lock( sys->d3d_dev );
 
@@ -621,9 +623,17 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
                  * display, do it preferrably when creating the texture */
                 assert(p_sys->renderSrc[0]!=NULL);
             }
-            // we should receive a source update if they don't match
-            assert( vd->source.i_height == texDesc.Height );
-            assert( vd->source.i_width == texDesc.Width );
+            if ( sys->picQuad.i_height != texDesc.Height ||
+                 sys->picQuad.i_width != texDesc.Width )
+            {
+                /* the decoder produced different sizes than the vout, we need to
+                 * adjust the vertex */
+                sys->picQuad.i_height = texDesc.Height;
+                sys->picQuad.i_width = texDesc.Width;
+
+                CommonPlacePicture(vd, &sys->area, &sys->sys);
+                UpdateSize(vd);
+            }
         }
     }
 
@@ -808,6 +818,16 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmtp, vlc_video_co
         }
     }
 
+    /* adjust the decoder sizes to have proper padding */
+    sys->picQuad.i_width  = fmt.i_width;
+    sys->picQuad.i_height = fmt.i_height;
+    if ( sys->picQuad.textureFormat->formatTexture != DXGI_FORMAT_R8G8B8A8_UNORM &&
+         sys->picQuad.textureFormat->formatTexture != DXGI_FORMAT_B5G6R5_UNORM )
+    {
+        sys->picQuad.i_width  = (sys->picQuad.i_width  + 0x01) & ~0x01;
+        sys->picQuad.i_height = (sys->picQuad.i_height + 0x01) & ~0x01;
+    }
+
     CommonPlacePicture(vd, &sys->area, &sys->sys);
 
     err = QueryDisplayFormat(vd, &fmt);
@@ -1055,9 +1075,11 @@ static int Direct3D11CreateFormatResources(vout_display_t *vd, const video_forma
         return VLC_EGENERIC;
     }
 
-    POINT source_rect = {
-        .x = vd->source.i_visible_width,
-        .y = vd->source.i_visible_height,
+    RECT source_rect = {
+        .left   = vd->fmt.i_x_offset,
+        .right  = vd->fmt.i_x_offset + vd->fmt.i_visible_width,
+        .top    = vd->fmt.i_y_offset,
+        .bottom = vd->fmt.i_y_offset + vd->fmt.i_visible_height,
     };
     if (!D3D11_UpdateQuadPosition(vd, sys->d3d_dev, &sys->picQuad, &source_rect, vd->source.orientation))
     {
@@ -1084,15 +1106,8 @@ static int Direct3D11CreateFormatResources(vout_display_t *vd, const video_forma
         /* we need a staging texture */
         ID3D11Texture2D *textures[D3D11_MAX_SHADER_VIEW] = {0};
         video_format_t texture_fmt = vd->source;
-
-        /* adjust the decoder sizes to have proper padding */
-        if ( sys->picQuad.textureFormat->formatTexture != DXGI_FORMAT_R8G8B8A8_UNORM &&
-             sys->picQuad.textureFormat->formatTexture != DXGI_FORMAT_B5G6R5_UNORM )
-        {
-            texture_fmt.i_width  = (texture_fmt.i_width  + 0x01) & ~0x01;
-            texture_fmt.i_height = (texture_fmt.i_height + 0x01) & ~0x01;
-        }
-
+        texture_fmt.i_width  = sys->picQuad.i_width;
+        texture_fmt.i_height = sys->picQuad.i_height;
         if (!is_d3d11_opaque(fmt->i_chroma))
             texture_fmt.i_chroma = sys->picQuad.textureFormat->fourcc;
 
@@ -1314,6 +1329,8 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
                 free(d3dquad);
                 continue;
             }
+            d3dquad->i_width    = r->fmt.i_width;
+            d3dquad->i_height   = r->fmt.i_height;
 
             d3dquad->textureFormat = sys->regionQuad.textureFormat;
             err = D3D11_AllocateQuad(vd, sys->d3d_dev, PROJECTION_MODE_RECTANGULAR, d3dquad);
@@ -1378,10 +1395,11 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
             continue;
         }
 
-        POINT output = {
-            .x = r->fmt.i_visible_width,
-            .y = r->fmt.i_visible_height,
-        };
+        RECT output;
+        output.left   = r->fmt.i_x_offset;
+        output.right  = r->fmt.i_x_offset + r->fmt.i_visible_width;
+        output.top    = r->fmt.i_y_offset;
+        output.bottom = r->fmt.i_y_offset + r->fmt.i_visible_height;
 
         D3D11_UpdateQuadPosition(vd, sys->d3d_dev, quad, &output, ORIENT_NORMAL);
 



More information about the vlc-commits mailing list