[PATCH 5/5] Rename color_fixup_supported to blit_supported support and add additional checks.

Roderick Colenbrander thunderbird2k at gmail.com
Thu Apr 1 16:58:53 CDT 2010


---
 dlls/wined3d/arb_program_shader.c |   54 +++++++++++++++++++++----
 dlls/wined3d/directx.c            |    4 +-
 dlls/wined3d/surface.c            |   80 +++++++++++++++++++++++++++++--------
 dlls/wined3d/wined3d_private.h    |    9 ++++-
 4 files changed, 119 insertions(+), 28 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 944eaad..29a0836 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -6840,31 +6840,67 @@ static void arbfp_blit_unset(IWineD3DDevice *iface) {
     LEAVE_GL();
 }
 
-static BOOL arbfp_blit_color_fixup_supported(const struct wined3d_gl_info *gl_info, struct color_fixup_desc fixup)
+static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+                                 const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool,
+                                 const struct wined3d_format_desc *src_format_desc,
+                                 const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool,
+                                 const struct wined3d_format_desc *dst_format_desc)
 {
-    enum complex_fixup complex_fixup;
+    enum complex_fixup src_fixup = get_complex_fixup(src_format_desc->color_fixup);
+    enum complex_fixup dst_fixup = get_complex_fixup(dst_format_desc->color_fixup);
 
     if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
     {
         TRACE("Checking support for fixup:\n");
-        dump_color_fixup_desc(fixup);
+        dump_color_fixup_desc(src_format_desc->color_fixup);
     }
 
-    if (is_identity_fixup(fixup))
+    if (blit_op != BLIT_OP_BLIT)
+    {
+        TRACE("Unsupported blit_op=%d\n", blit_op);
+        return FALSE;
+    }
+
+    /* In general we don't support any destination fixups except for P8. P8 fixup
+     * can occur in three cases:
+     * 1) Blit from p8 source to p8 destination, this is a source fixup and the
+     *    destination fixup can be ignored.
+     * 2) LockRect on surface, LoadLocation takes care of the 'destination fixup'.
+     * 3) RealizePalette refreshes the palette of a surface. The surface is then
+     *    both the source (the sysmem / texture copy) and the destination (drawable).
+     *
+     * No scaling should be performed since interpolation on palette indices doesn't
+     * make any sense. Flipping is allowed hence 'abs'.
+     */
+    if (src_fixup == dst_fixup && dst_fixup == COMPLEX_FIXUP_P8 && src_rect && dst_rect
+        && (src_rect->right - src_rect->left == dst_rect->right - dst_rect->left)
+        && (abs(src_rect->bottom - src_rect->top) == abs(dst_rect->bottom - dst_rect->top))
+        && (dst_usage & WINED3DUSAGE_RENDERTARGET))
+    {
+        TRACE("[OK]\n");
+        return TRUE;
+    }
+
+    if (!is_identity_fixup(dst_format_desc->color_fixup))
+    {
+        TRACE("Destination fixups are not supported\n");
+        return FALSE;
+    }
+
+    if (is_identity_fixup(src_format_desc->color_fixup))
     {
         TRACE("[OK]\n");
         return TRUE;
     }
 
     /* We only support YUV conversions. */
-    if (!is_complex_fixup(fixup))
+    if (!is_complex_fixup(src_format_desc->color_fixup))
     {
         TRACE("[FAILED]\n");
         return FALSE;
     }
 
-    complex_fixup = get_complex_fixup(fixup);
-    switch(complex_fixup)
+    switch(src_fixup)
     {
         case COMPLEX_FIXUP_YUY2:
         case COMPLEX_FIXUP_UYVY:
@@ -6874,7 +6910,7 @@ static BOOL arbfp_blit_color_fixup_supported(const struct wined3d_gl_info *gl_in
             return TRUE;
 
         default:
-            FIXME("Unsupported YUV fixup %#x\n", complex_fixup);
+            FIXME("Unsupported YUV fixup %#x\n", src_fixup);
             TRACE("[FAILED]\n");
             return FALSE;
     }
@@ -6891,7 +6927,7 @@ const struct blit_shader arbfp_blit = {
     arbfp_blit_free,
     arbfp_blit_set,
     arbfp_blit_unset,
-    arbfp_blit_color_fixup_supported,
+    arbfp_blit_supported,
     arbfp_blit_color_fill
 };
 
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 464e43e..9e0a2fc 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -3636,7 +3636,9 @@ static BOOL CheckSurfaceCapability(struct wined3d_adapter *adapter,
     if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE;
 
     /* If opengl can't process the format natively, the blitter may be able to convert it */
-    if (adapter->blitter->color_fixup_supported(&adapter->gl_info, check_format_desc->color_fixup))
+    if (adapter->blitter->blit_supported(&adapter->gl_info, BLIT_OP_BLIT,
+                                         NULL, WINED3DPOOL_DEFAULT, 0, check_format_desc,
+                                         NULL, WINED3DPOOL_DEFAULT, 0, adapter_format_desc))
     {
         TRACE_(d3d_caps)("[OK]\n");
         return TRUE;
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 95889e4..8e1207c 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2120,6 +2120,8 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
     const struct wined3d_format_desc *glDesc = This->resource.format_desc;
     IWineD3DDeviceImpl *device = This->resource.device;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    BOOL blit_supported = FALSE;
+    RECT rect = {0, 0, This->pow2Width, This->pow2Height};
 
     /* Default values: From the surface */
     *format = glDesc->glFormat;
@@ -2145,6 +2147,10 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             /* ****************
                 Paletted Texture
                 **************** */
+            blit_supported = device->blitter->blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT,
+                                                             &rect, This->resource.usage, This->resource.pool,
+                                                             This->resource.format_desc, &rect, This->resource.usage,
+                                                             This->resource.pool, This->resource.format_desc);
 
             /* Use conversion when the blit_shader backend supports it. It only supports this in case of
              * texturing. Further also use conversion in case of color keying.
@@ -2152,8 +2158,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
              * in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which
              * conflicts with this.
              */
-            if (!((device->blitter->color_fixup_supported(gl_info, This->resource.format_desc->color_fixup)
-                    && device->render_targets && This == (IWineD3DSurfaceImpl*)device->render_targets[0]))
+            if (!((blit_supported && device->render_targets && This == (IWineD3DSurfaceImpl*)device->render_targets[0]))
                     || colorkey_active || !use_texturing)
             {
                 *format = GL_RGBA;
@@ -2167,7 +2172,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
                 }
             }
             /* TODO: this check is evil and should die (it basically checks which blitter backend is used) */
-            else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && device->blitter->color_fixup_supported(gl_info, This->resource.format_desc->color_fixup))
+            else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && blit_supported)
             {
                 *format = GL_ALPHA;
                 *type = GL_UNSIGNED_BYTE;
@@ -4047,7 +4052,9 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
             dump_color_fixup_desc(This->resource.format_desc->color_fixup);
         }
 
-        if (!myDevice->blitter->color_fixup_supported(&myDevice->adapter->gl_info, Src->resource.format_desc->color_fixup))
+        if (!myDevice->blitter->blit_supported(&myDevice->adapter->gl_info, BLIT_OP_BLIT,
+                                               &src_rect, Src->resource.usage, Src->resource.pool, Src->resource.format_desc,
+                                               &dst_rect, This->resource.usage, This->resource.pool, This->resource.format_desc))
         {
             FIXME("Source format %s has an unsupported fixup:\n",
                     debug_d3dformat(Src->resource.format_desc->format));
@@ -4291,8 +4298,12 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface)
             || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
     {
         IWineD3DDeviceImpl *device = This->resource.device;
+        RECT rect = {0, 0, This->pow2Width, This->pow2Height};
+
         if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) &&
-            device->blitter->color_fixup_supported(&device->adapter->gl_info, This->resource.format_desc->color_fixup))
+            device->blitter->blit_supported(&device->adapter->gl_info, BLIT_OP_BLIT, &rect, This->resource.usage,
+                                            This->resource.pool, This->resource.format_desc, &rect, This->resource.pool,
+                                            This->resource.usage, This->resource.format_desc))
         {
             /* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */
             IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL);
@@ -5143,30 +5154,61 @@ static void ffp_blit_unset(IWineD3DDevice *iface)
     LEAVE_GL();
 }
 
-static BOOL ffp_blit_color_fixup_supported(const struct wined3d_gl_info *gl_info, struct color_fixup_desc fixup)
+static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+                               const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool,
+                               const struct wined3d_format_desc *src_format_desc,
+                               const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool,
+                               const struct wined3d_format_desc *dst_format_desc)
 {
-    enum complex_fixup complex_fixup;
+    enum complex_fixup src_fixup = get_complex_fixup(src_format_desc->color_fixup);
+    enum complex_fixup dst_fixup = get_complex_fixup(dst_format_desc->color_fixup);
 
     if (TRACE_ON(d3d_surface) && TRACE_ON(d3d))
     {
         TRACE("Checking support for fixup:\n");
-        dump_color_fixup_desc(fixup);
+        dump_color_fixup_desc(src_format_desc->color_fixup);
     }
 
-    /* We only support identity conversions. */
-    if (is_identity_fixup(fixup))
+    if (blit_op != BLIT_OP_BLIT)
     {
-        TRACE("[OK]\n");
-        return TRUE;
+        TRACE("Unsupported blit_op=%d\n", blit_op);
+        return FALSE;
     }
 
-    complex_fixup = get_complex_fixup(fixup);
-    if(complex_fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE])
+    /* In general we don't support any source or destination fixups except for P8.
+     * P8 fixup can occur in three cases:
+     * 1) Blit from p8 source to p8 destination, this is a source fixup and the
+     *    destination fixup can be ignored.
+     * 2) LockRect on surface, LoadLocation takes care of the 'destination fixup'.
+     * 3) RealizePalette refreshes the palette of a surface. The surface is then
+     *    both the source (the sysmem / texture copy) and the destination (drawable).
+     *
+     * No scaling should be performed since interpolation on palette indices doesn't
+     * make any sense. Flipping is allowed hence 'abs'.
+     */
+    if (src_fixup == dst_fixup && dst_fixup == COMPLEX_FIXUP_P8 && src_rect && dst_rect
+        && gl_info->supported[EXT_PALETTED_TEXTURE]
+        && (src_rect->right - src_rect->left == dst_rect->right - dst_rect->left)
+        && (abs(src_rect->bottom - src_rect->top) == abs(dst_rect->bottom - dst_rect->top))
+        && (dst_usage & WINED3DUSAGE_RENDERTARGET))
     {
         TRACE("P8 fixup supported\n");
         return TRUE;
     }
 
+    if (!is_identity_fixup(dst_format_desc->color_fixup))
+    {
+        TRACE("Destination fixups are not supported\n");
+        return FALSE;
+    }
+
+    /* We only support identity conversions. */
+    if (is_identity_fixup(src_format_desc->color_fixup))
+    {
+        TRACE("[OK]\n");
+        return TRUE;
+    }
+
     TRACE("[FAILED]\n");
     return FALSE;
 }
@@ -5182,7 +5224,7 @@ const struct blit_shader ffp_blit =  {
     ffp_blit_free,
     ffp_blit_set,
     ffp_blit_unset,
-    ffp_blit_color_fixup_supported,
+    ffp_blit_supported,
     ffp_blit_color_fill
 };
 
@@ -5207,7 +5249,11 @@ static void cpu_blit_unset(IWineD3DDevice *iface)
 {
 }
 
-static BOOL cpu_blit_color_fixup_supported(const struct wined3d_gl_info *gl_info, struct color_fixup_desc fixup)
+static BOOL cpu_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+                               const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool,
+                               const struct wined3d_format_desc *src_format_desc,
+                               const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool,
+                               const struct wined3d_format_desc *dst_format_desc)
 {
     return FALSE;
 }
@@ -5226,6 +5272,6 @@ const struct blit_shader cpu_blit =  {
     cpu_blit_free,
     cpu_blit_set,
     cpu_blit_unset,
-    cpu_blit_color_fixup_supported,
+    cpu_blit_supported,
     cpu_blit_color_fill
 };
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2555217..88c8ba9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1168,6 +1168,11 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
         const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
 
+enum blit_operation
+{
+    BLIT_OP_BLIT
+};
+
 /* Shaders for color conversions in blits */
 struct blit_shader
 {
@@ -1175,7 +1180,9 @@ struct blit_shader
     void (*free_private)(IWineD3DDevice *iface);
     HRESULT (*set_shader)(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface);
     void (*unset_shader)(IWineD3DDevice *iface);
-    BOOL (*color_fixup_supported)(const struct wined3d_gl_info *gl_info, struct color_fixup_desc fixup);
+    BOOL (*blit_supported)(const struct wined3d_gl_info *gl_info, enum blit_operation blit_op,
+                           const RECT *src_rect, DWORD src_usage, WINED3DPOOL src_pool, const struct wined3d_format_desc *src_format_desc,
+                           const RECT *dst_rect, DWORD dst_usage, WINED3DPOOL dst_pool, const struct wined3d_format_desc *dst_format_desc);
     HRESULT (*color_fill)(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color);
 };
 
-- 
1.6.3.3




More information about the wine-patches mailing list