[PATCH] Rewrite CheckDeviceFormat. The old version made too much usage flags pass and the function was a hell to read and maintain. The new version has a small codepath for each resource type. Each check only checks the usage flags which msdn allows and it makes use of the new helper functions. The function is a lot easier to understand and maintain while the values it returns are much more correct that before.

Roderick Colenbrander thunderbird2k at gmx.net
Tue Mar 4 03:23:23 CST 2008


---
 dlls/wined3d/directx.c |  618 +++++++++++++++++++++++-------------------------
 1 files changed, 296 insertions(+), 322 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index ec5a895..06f7b48 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2217,9 +2217,12 @@ static BOOL CheckVertexTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat
     return FALSE;
 }
 
+
 static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
                                               WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat) {
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
+    DWORD UsageCaps = 0;
+
     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
           This,
           Adapter,
@@ -2233,374 +2236,345 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
         return WINED3DERR_INVALIDCALL;
     }
 
-    if (Usage & WINED3DUSAGE_QUERY_FILTER) {
-        switch (CheckFormat) {
-            /* Filtering not supported */
-            case WINED3DFMT_R32F:
-            case WINED3DFMT_A32B32G32R32F:
-                TRACE_(d3d_caps)("[FAILED]\n");
-                return WINED3DERR_NOTAVAILABLE;
-            default:
-                break;
-        }
+    /* This format is nothing special and it is supported perfectly.
+     * However, ati and nvidia driver on windows do not mark this format as
+     * supported (tested with the dxCapsViewer) and pretending to
+     * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
+     * So do the same as Windows drivers and pretend not to support it on dx8 and 9
+     * Enable it on dx7. It will need additional checking on dx10 when we support it.
+     */
+    if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
+        TRACE_(d3d_caps)("[FAILED]\n");
+        return WINED3DERR_NOTAVAILABLE;
     }
 
-    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
-        if(!GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
-            TRACE_(d3d_caps)("[FAILED] - No mipmap generation support\n");
-            return WINED3DERR_NOTAVAILABLE;
-        }
-    }
+    /* Note most drivers (ATI/Intel/Nvidia) seem to set D3DUSAGE_WRITEONLY and others while MSDN doesn't document them for standard resource types. */
 
-    if(RType == WINED3DRTYPE_VOLUMETEXTURE) {
-        if(!GL_SUPPORT(EXT_TEXTURE3D)) {
-            TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
-            return WINED3DERR_NOTAVAILABLE;
-        }
-        /* Filter formats that need conversion; For one part, this conversion is unimplemented,
-         * and volume textures are huge, so it would be a big performance hit. Unless we hit an
-         * app needing one of those formats, don't advertize them to avoid leading apps into
-         * temptation. The windows drivers don't support most of those formats on volumes anyway,
-         * except of R32F.
+    /* TODO:
+     *   - D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+     *   - D3DUSAGE_QUERY_SRGBWRITE
+     *   - D3DUSAGE_QUERY_WRAPANDMIP
+     *   - some new D3D9ex queries?
+     */
+
+    if(RType == WINED3DRTYPE_CUBETEXTURE) {
+        /* Cubetexture allows:
+         *                    - D3DUSAGE_AUTOGENMIPMAP
+         *                    - D3DUSAGE_DEPTHSTENCIL
+         *                    - D3DUSAGE_DYNAMIC
+         *                    - D3DUSAGE_NONSECURE (d3d9ex)
+         *                    - D3DUSAGE_RENDERTARGET
+         *                    - D3DUSAGE_SOFTWAREPROCESSING
          */
-        switch(CheckFormat) {
-            case WINED3DFMT_P8:
-            case WINED3DFMT_A4L4:
-            case WINED3DFMT_R32F:
-            case WINED3DFMT_R16F:
-            case WINED3DFMT_X8L8V8U8:
-            case WINED3DFMT_L6V5U5:
-            case WINED3DFMT_G16R16:
-                TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
-                return WINED3DERR_NOTAVAILABLE;
 
-            case WINED3DFMT_Q8W8V8U8:
-            case WINED3DFMT_V16U16:
-            if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
-                TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
-                return WINED3DERR_NOTAVAILABLE;
-            }
-            break;
+        if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
+            /* Check if the texture format is around */
+            if(CheckTextureCapability(Adapter, CheckFormat)) {
+                /* No usage checks were requested, so return because we know that the format is supported */
+                if(!Usage)
+                    return WINED3D_OK;
 
-            case WINED3DFMT_V8U8:
-            if(!GL_SUPPORT(NV_TEXTURE_SHADER) || !GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
-                TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
-                return WINED3DERR_NOTAVAILABLE;
-            }
-            break;
+                if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
+                    /* Check for automatic mipmap generation support */
+                    if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
+                        UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
+                    } else {
+                        /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUOTGEN instead of D3D_OK */
+                        TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
+                    }
+                }
 
-            case WINED3DFMT_DXT1:
-            case WINED3DFMT_DXT2:
-            case WINED3DFMT_DXT3:
-            case WINED3DFMT_DXT4:
-            case WINED3DFMT_DXT5:
-                /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
-                 * compressed texture results in an error. While the D3D refrast does
-                 * support s3tc volumes, at least the nvidia windows driver does not, so
-                 * we're free not to support this format.
-                 */
-                TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
-                return WINED3DERR_NOTAVAILABLE;
+                /* Always report dynamic locking */
+                if(Usage & WINED3DUSAGE_DYNAMIC)
+                    UsageCaps |= WINED3DUSAGE_DYNAMIC;
+
+                if(Usage & WINED3DUSAGE_RENDERTARGET) {
+                    if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
+                        UsageCaps |= WINED3DUSAGE_RENDERTARGET;
+                    } else {
+                        TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
+                        return WINED3DERR_NOTAVAILABLE;
+                    }
+                }
 
-            default:
-                /* Do nothing, continue with checking the format below */
-                break;
-        }
-    }
-    /* TODO: Check support against more of the WINED3DUSAGE_QUERY_* constants */
-    if (Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
-        if (!GL_LIMITS(vertex_samplers)) {
-            TRACE_(d3d_caps)("[FAILED]\n");
+                /* Always report software processing */
+                if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
+                    UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
+
+                /* Check QUERY_FILTER support */
+                if(Usage & WINED3DUSAGE_QUERY_FILTER) {
+                    if(CheckFilterCapability(CheckFormat)) {
+                        UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
+                    } else {
+                        TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
+                        return WINED3DERR_NOTAVAILABLE;
+                    }
+                }
+
+                /* Check QUERY_SRGBREAD support */
+                if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
+                    if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
+                        UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
+                    } else {
+                        TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
+                        return WINED3DERR_NOTAVAILABLE;
+                    }
+                }
+
+                /* Check QUERY_VERTEXTEXTURE support */
+                if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
+                    if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
+                        UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
+                    } else {
+                        TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
+                        return WINED3DERR_NOTAVAILABLE;
+                    }
+                }
+            }
+        } else {
+            TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
             return WINED3DERR_NOTAVAILABLE;
         }
+    } else if(RType == WINED3DRTYPE_SURFACE) {
+        /* Surface allows:
+         *                - D3DUSAGE_DEPTHSTENCIL
+         *                - D3DUSAGE_NONSECURE (d3d9ex)
+         *                - D3DUSAGE_RENDERTARGET
+         */
 
-        switch (CheckFormat) {
-            case WINED3DFMT_A32B32G32R32F:
-                if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
-                    TRACE_(d3d_caps)("[FAILED]\n");
-                    return WINED3DERR_NOTAVAILABLE;
-                }
-                TRACE_(d3d_caps)("[OK]\n");
-                return WINED3D_OK;
+        /* TODO: what should we do for Usage=0? */
 
-            default:
-                TRACE_(d3d_caps)("[FAILED]\n");
+        /* Note that at least on Ati/Intel/Nviida rendertarget and depthstencil are mutual exclusive for surfaces */
+        if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
+            if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
+                UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
+            } else {
+                TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
                 return WINED3DERR_NOTAVAILABLE;
+            }
         }
-    }
 
-    if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
-        switch (CheckFormat) {
-            /* In theory we could do all formats, just fetch them accordingly should the buffer be locked.
-             * Windows supports only those 3, and enumerating the other formats confuses applications
-             */
-            case WINED3DFMT_D24S8:
-            case WINED3DFMT_D24X8:
-            case WINED3DFMT_D16:
-                TRACE_(d3d_caps)("[OK]\n");
-                return WINED3D_OK;
-            case WINED3DFMT_D16_LOCKABLE:
-            case WINED3DFMT_D24FS8:
-            case WINED3DFMT_D32F_LOCKABLE:
-            case WINED3DFMT_D24X4S4:
-            case WINED3DFMT_D15S1:
-            case WINED3DFMT_D32:
-                TRACE_(d3d_caps)("[FAILED]. Disabled because not enumerated on windows\n");
-                return WINED3DERR_NOTAVAILABLE;
-            default:
-                TRACE_(d3d_caps)("[FAILED]\n");
+        if(Usage & WINED3DUSAGE_RENDERTARGET) {
+            if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
+                UsageCaps |= WINED3DUSAGE_RENDERTARGET;
+            } else {
+                TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
                 return WINED3DERR_NOTAVAILABLE;
+            }
         }
-    } else if(Usage & WINED3DUSAGE_RENDERTARGET) {
-        switch (CheckFormat) {
-            case WINED3DFMT_R8G8B8:
-            case WINED3DFMT_A8R8G8B8:
-            case WINED3DFMT_X8R8G8B8:
-            case WINED3DFMT_R5G6B5:
-            case WINED3DFMT_X1R5G5B5:
-            case WINED3DFMT_A1R5G5B5:
-            case WINED3DFMT_A4R4G4B4:
-            case WINED3DFMT_R3G3B2:
-            case WINED3DFMT_X4R4G4B4:
-            case WINED3DFMT_A8B8G8R8:
-            case WINED3DFMT_X8B8G8R8:
-            case WINED3DFMT_P8:
-            case WINED3DFMT_G16R16:
-                TRACE_(d3d_caps)("[OK]\n");
+    }
+    else if(RType == WINED3DRTYPE_TEXTURE) {
+        /* Texture allows:
+         *                - D3DUSAGE_AUTOGENMIPMAP
+         *                - D3DUSAGE_DEPTHSTENCIL
+         *                - D3DUSAGE_DMAP
+         *                - D3DUSAGE_DYNAMIC
+         *                - D3DUSAGE_NONSECURE (d3d9ex)
+         *                - D3DUSAGE_RENDERTARGET
+         *                - D3DUSAGE_SOFTWAREPROCESSING
+         *                - D3DUSAGE_TEXTAPI (d3d9ex)
+         */
+
+        /* Check if the texture format is around */
+        if(CheckTextureCapability(Adapter, CheckFormat)) {
+            /* No usage checks were requested, so return because we know that the format is supported */
+            if(!Usage)
                 return WINED3D_OK;
-            case WINED3DFMT_R16F:
-            case WINED3DFMT_A16B16G16R16F:
-                if (!GL_SUPPORT(ARB_HALF_FLOAT_PIXEL) || !GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
-                    TRACE_(d3d_caps)("[FAILED]\n");
+
+            if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
+                /* Check for automatic mipmap generation support */
+                if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
+                    UsageCaps |= WINED3DUSAGE_AUTOGENMIPMAP;
+                } else {
+                    /* When autogenmipmap isn't around continue and return WINED3DOK_NOAUOTGEN instead of D3D_OK */
+                    TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
+                }
+            }
+
+            /* Always report dynamic locking */
+            if(Usage & WINED3DUSAGE_DYNAMIC)
+                UsageCaps |= WINED3DUSAGE_DYNAMIC;
+
+            if(Usage & WINED3DUSAGE_RENDERTARGET) {
+                if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
+                    UsageCaps |= WINED3DUSAGE_RENDERTARGET;
+                } else {
+                    TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
                     return WINED3DERR_NOTAVAILABLE;
                 }
-                TRACE_(d3d_caps)("[OK]\n");
-                return WINED3D_OK;
-            case WINED3DFMT_A32B32G32R32F:
-               if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
-                    TRACE_(d3d_caps)("[FAILED]\n");
+            }
+
+            /* Always report software processing */
+            if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
+                UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
+
+            /* Check QUERY_FILTER support */
+            if(Usage & WINED3DUSAGE_QUERY_FILTER) {
+                if(CheckFilterCapability(CheckFormat)) {
+                    UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
+                } else {
+                    TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
                     return WINED3DERR_NOTAVAILABLE;
                 }
-                TRACE_(d3d_caps)("[OK]\n");
-                return WINED3D_OK;
-            default:
-                TRACE_(d3d_caps)("[FAILED]\n");
-                return WINED3DERR_NOTAVAILABLE;
-        }
-    } else if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
-        if(GL_SUPPORT(NV_REGISTER_COMBINERS) && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
-            switch (CheckFormat) {
-                case WINED3DFMT_V8U8:
-                    TRACE_(d3d_caps)("[OK]\n");
-                    return WINED3D_OK;
-                /* TODO: Other bump map formats */
-                default:
-                    TRACE_(d3d_caps)("[FAILED]\n");
+            }
+
+            /* Check QUERY_LEGACYBUMPMAP support */
+            if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
+                if(CheckBumpMapCapability(Adapter, CheckFormat)) {
+                    UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
+                } else {
+                    TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
                     return WINED3DERR_NOTAVAILABLE;
+                }
             }
-        }
-        if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
-            switch (CheckFormat) {
-                case WINED3DFMT_V8U8:
-                    TRACE_(d3d_caps)("[OK]\n");
-                    return WINED3D_OK;
-                default:
-                    TRACE_(d3d_caps)("[FAILED]\n");
+
+            /* Check QUERY_SRGBREAD support */
+            if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
+                if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
+                    UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
+                } else {
+                    TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
                     return WINED3DERR_NOTAVAILABLE;
+                }
             }
-        }
-        TRACE_(d3d_caps)("[FAILED]\n");
-        return WINED3DERR_NOTAVAILABLE;
-    }
 
-    /* Check for supported sRGB formats (Texture loading and framebuffer) */
-    if (Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
-        if(!GL_SUPPORT(EXT_TEXTURE_SRGB)) {
-            TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
-        }
+            /* Check QUERY_VERTEXTEXTURE support */
+            if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
+                if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
+                    UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
+                } else {
+                    TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
+                    return WINED3DERR_NOTAVAILABLE;
+                }
+            }
+        } else if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
 
-        switch (CheckFormat) {
-            case WINED3DFMT_A8R8G8B8:
-            case WINED3DFMT_X8R8G8B8:
-            case WINED3DFMT_A4R4G4B4:
-            case WINED3DFMT_L8:
-            case WINED3DFMT_A8L8:
-            case WINED3DFMT_DXT1:
-            case WINED3DFMT_DXT2:
-            case WINED3DFMT_DXT3:
-            case WINED3DFMT_DXT4:
-            case WINED3DFMT_DXT5:
-                TRACE_(d3d_caps)("[OK]\n");
-                break; /* Continue with checking other flags */
+            /* For now only offer DEPTHSTENCIL. Later on we should also offer DYNAMIC
+             * but according to Stefan we don't support it right now. */
+            if(Usage & WINED3DUSAGE_DEPTHSTENCIL)
+                UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
 
-            default:
-                TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
-                return WINED3DERR_NOTAVAILABLE;
+            /* Always report software processing */
+            if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
+                UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
         }
-    }
-
-    /* This format is nothing special and it is supported perfectly.
-     * However, ati and nvidia driver on windows do not mark this format as
-     * supported (tested with the dxCapsViewer) and pretending to
-     * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
-     * So do the same as Windows drivers and pretend not to support it on dx8 and 9
-     * Enable it on dx7. It will need additional checking on dx10 when we support it.
-     */
-    if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
-        TRACE_(d3d_caps)("[FAILED]\n");
-        return WINED3DERR_NOTAVAILABLE;
-    }
-
-    switch (CheckFormat) {
-
-        /*****
-         *  supported: RGB(A) formats
-         */
-        case WINED3DFMT_R8G8B8: /* Enable for dx7, blacklisted for 8 and 9 above */
-        case WINED3DFMT_A8R8G8B8:
-        case WINED3DFMT_X8R8G8B8:
-        case WINED3DFMT_R5G6B5:
-        case WINED3DFMT_X1R5G5B5:
-        case WINED3DFMT_A1R5G5B5:
-        case WINED3DFMT_A4R4G4B4:
-        case WINED3DFMT_R3G3B2:
-        case WINED3DFMT_A8:
-        case WINED3DFMT_X4R4G4B4:
-        case WINED3DFMT_A8B8G8R8:
-        case WINED3DFMT_X8B8G8R8:
-        case WINED3DFMT_A2R10G10B10:
-        case WINED3DFMT_A2B10G10R10:
-        case WINED3DFMT_G16R16:
-            TRACE_(d3d_caps)("[OK]\n");
-            return WINED3D_OK;
-
-        /*****
-         *  supported: Palettized
+    } else if((RType == WINED3DRTYPE_VOLUME) || (RType == WINED3DRTYPE_VOLUMETEXTURE)) {
+        /* Volume is to VolumeTexture what Surface is to Texture but its usage caps are not documented.
+         * Most driver seem to offer (nearly) the same on Volume and VolumeTexture, so do that too.
+         *
+         * Volumetexture allows:
+         *                      - D3DUSAGE_DYNAMIC
+         *                      - D3DUSAGE_NONSECURE (d3d9ex)
+         *                      - D3DUSAGE_SOFTWAREPROCESSING
          */
-        case WINED3DFMT_P8:
-            TRACE_(d3d_caps)("[OK]\n");
-            return WINED3D_OK;
 
-        /*****
-         *  Supported: (Alpha)-Luminance
-         */
-        case WINED3DFMT_L8:
-        case WINED3DFMT_A8L8:
-        case WINED3DFMT_A4L4:
-            TRACE_(d3d_caps)("[OK]\n");
-            return WINED3D_OK;
+        /* Check volume texture and volume usage caps */
+        if(GL_SUPPORT(EXT_TEXTURE3D)) {
+            if(CheckTextureCapability(Adapter, CheckFormat) == FALSE) {
+                TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
+                return WINED3DERR_NOTAVAILABLE;
+            }
 
-        /*****
-         *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
-         *  GL_NV_texture_shader), but advertized to make apps happy.
-         *  Enable some because games often fail when they are not available
-         *  and are still playable even without bump mapping
-         */
-        case WINED3DFMT_V8U8:
-        case WINED3DFMT_V16U16:
-        case WINED3DFMT_L6V5U5:
-        case WINED3DFMT_X8L8V8U8:
-        case WINED3DFMT_Q8W8V8U8:
-            WARN_(d3d_caps)("[Not supported, but pretended to do]\n");
-            return WINED3D_OK;
+            /* Filter formats that need conversion; For one part, this conversion is unimplemented,
+             * and volume textures are huge, so it would be a big performance hit. Unless we hit an
+             * app needing one of those formats, don't advertize them to avoid leading apps into
+             * temptation. The windows drivers don't support most of those formats on volumes anyway,
+             * except for R32F.
+             */
+            switch(CheckFormat) {
+                case WINED3DFMT_P8:
+                case WINED3DFMT_A4L4:
+                case WINED3DFMT_R32F:
+                case WINED3DFMT_R16F:
+                case WINED3DFMT_X8L8V8U8:
+                case WINED3DFMT_L6V5U5:
+                case WINED3DFMT_G16R16:
+                    TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
+                    return WINED3DERR_NOTAVAILABLE;
 
-        /* Those are not advertized by the nvidia windows driver, and not
-         * supported natively by GL_NV_texture_shader or GL_ATI_envmap_bumpmap.
-         * WINED3DFMT_A2W10V10U10 could be loaded into shaders using the unsigned
-         * ARGB format if needed
-         */
-        case WINED3DFMT_W11V11U10:
-        case WINED3DFMT_A2W10V10U10:
-            WARN_(d3d_caps)("[FAILED]\n");
-            return WINED3DERR_NOTAVAILABLE;
+                case WINED3DFMT_DXT1:
+                case WINED3DFMT_DXT2:
+                case WINED3DFMT_DXT3:
+                case WINED3DFMT_DXT4:
+                case WINED3DFMT_DXT5:
+                    /* The GL_EXT_texture_compression_s3tc spec requires that loading an s3tc
+                     * compressed texture results in an error. While the D3D refrast does
+                     * support s3tc volumes, at least the nvidia windows driver does not, so
+                     * we're free not to support this format.
+                     */
+                    TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
+                    return WINED3DERR_NOTAVAILABLE;
 
-        case WINED3DFMT_DXT1:
-        case WINED3DFMT_DXT2:
-        case WINED3DFMT_DXT3:
-        case WINED3DFMT_DXT4:
-        case WINED3DFMT_DXT5:
-            if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
-                TRACE_(d3d_caps)("[OK]\n");
-                return WINED3D_OK;
-            } else {
-                TRACE_(d3d_caps)("[FAILED]\n");
-                return WINED3DERR_NOTAVAILABLE;
+                default:
+                    /* Do nothing, continue with checking the format below */
+                    break;
             }
 
+            /* No usage checks were requested, so return because we know that the format is supported */
+            if(!Usage)
+                return WINED3D_OK;
 
-        /*****
-         *  Odd formats - not supported
-         */
-        case WINED3DFMT_VERTEXDATA:
-        case WINED3DFMT_INDEX16:
-        case WINED3DFMT_INDEX32:
-        case WINED3DFMT_Q16W16V16U16:
-            TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
-            return WINED3DERR_NOTAVAILABLE;
-
-        /*****
-         *  WINED3DFMT_CxV8U8: Not supported right now
-         */
-        case WINED3DFMT_CxV8U8:
-            TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
-            return WINED3DERR_NOTAVAILABLE;
+            /* Always report dynamic locking */
+            if(Usage & WINED3DUSAGE_DYNAMIC)
+                UsageCaps |= WINED3DUSAGE_DYNAMIC;
 
-            /* Not supported */
-        case WINED3DFMT_A16B16G16R16:
-        case WINED3DFMT_A8R3G3B2:
-            TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
-            return WINED3DERR_NOTAVAILABLE;
+            /* Always report software processing */
+            if(Usage & WINED3DUSAGE_SOFTWAREPROCESSING)
+                UsageCaps |= WINED3DUSAGE_SOFTWAREPROCESSING;
 
-            /* Floating point formats */
-        case WINED3DFMT_R16F:
-        case WINED3DFMT_A16B16G16R16F:
-            if(GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
-                TRACE_(d3d_caps)("[OK]\n");
-                return WINED3D_OK;
-            } else {
-                TRACE_(d3d_caps)("[FAILED]\n");
-                return WINED3DERR_NOTAVAILABLE;
-            }
-        case WINED3DFMT_R32F:
-        case WINED3DFMT_A32B32G32R32F:
-            if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
-                TRACE_(d3d_caps)("[OK]\n");
-                return WINED3D_OK;
-            } else {
-                TRACE_(d3d_caps)("[FAILED]\n");
-                return WINED3DERR_NOTAVAILABLE;
+            /* Check QUERY_FILTER support */
+            if(Usage & WINED3DUSAGE_QUERY_FILTER) {
+                if(CheckFilterCapability(CheckFormat)) {
+                    UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
+                } else {
+                    TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
+                    return WINED3DERR_NOTAVAILABLE;
+                }
             }
 
-        case WINED3DFMT_G16R16F:
-        case WINED3DFMT_G32R32F:
-            TRACE_(d3d_caps)("[FAILED]\n");
-            return WINED3DERR_NOTAVAILABLE;
-
-        /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
-         * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
-         * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
-         * We can do instancing with all shader versions, but we need vertex shaders.
-         *
-         * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
-         * to enable instancing. WineD3D doesn't need that and just ignores it.
-         *
-         * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
-         */
-        case WINEMAKEFOURCC('I','N','S','T'):
-            TRACE("ATI Instancing check hack\n");
-            if(GL_SUPPORT(ARB_VERTEX_PROGRAM) || GL_SUPPORT(ARB_VERTEX_SHADER)) {
-                TRACE_(d3d_caps)("[OK]\n");
-                return WINED3D_OK;
-            } else {
-                TRACE_(d3d_caps)("[FAILED]\n");
-                return WINED3DERR_NOTAVAILABLE;
+            /* Check QUERY_SRGBREAD support */
+            if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
+                if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
+                    UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
+                } else {
+                    TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
+                    return WINED3DERR_NOTAVAILABLE;
+                }
             }
 
-        default:
-            break;
+            /* Check QUERY_VERTEXTEXTURE support */
+            if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
+                if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
+                    UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
+                } else {
+                    TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
+                    return WINED3DERR_NOTAVAILABLE;
+                }
+            }
+        } else {
+            TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
+            return WINED3DERR_NOTAVAILABLE;
+        }
+    } else if((RType == WINED3DRTYPE_INDEXBUFFER) || (RType == WINED3DRTYPE_VERTEXBUFFER)){
+        /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
+        TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
+        return WINED3DERR_NOTAVAILABLE;
     }
 
-    TRACE_(d3d_caps)("[FAILED]\n");
+    /* When the UsageCaps exactly match Usage return WINED3D_OK except for the situation in which
+     * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
+     * usage flags match. */
+    if(UsageCaps == Usage) {
+        return WINED3D_OK;
+    } else if(UsageCaps == (Usage & ~WINED3DUSAGE_AUTOGENMIPMAP)) {
+        /* CheckDeviceFormat bails out on all unsupported usage flags except for AUTOGENMIPMAP */
+        if((Usage & WINED3DUSAGE_AUTOGENMIPMAP) && !GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
+            return WINED3DOK_NOAUTOGEN;
+        }
+    } else {
+        TRACE_(d3d_caps)("[FAILED] - Usage=%#08x requested but only %#08x is available\n", Usage, UsageCaps);
+        return WINED3DERR_NOTAVAILABLE;
+    }
     return WINED3DERR_NOTAVAILABLE;
 }
 
-- 
1.5.3.4


--========GMX15871204622905335251--



More information about the wine-patches mailing list