[PATCH 1/5] wined3d: Introduce wined3d_device_check_format_support().

Chip Davis wine at gitlab.winehq.org
Wed May 25 19:05:07 CDT 2022


From: Chip Davis <cdavis5x at gmail.com>

Signed-off-by: Chip Davis <cdavis5x at gmail.com>
---
 dlls/wined3d/device.c     | 193 ++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d.spec |   1 +
 include/wine/wined3d.h    |  49 ++++++++++
 3 files changed, 243 insertions(+)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index c6a6de93123..089df0d37fc 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4279,6 +4279,199 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
     TRACE("Applied stateblock %p.\n", stateblock);
 }
 
+HRESULT CDECL wined3d_device_check_format_support(const struct wined3d_device *device,
+        enum wined3d_format_id format_id, unsigned int *format_support,
+        unsigned int *format_support_2)
+{
+    const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+    const struct wined3d_adapter *adapter = device->adapter;
+    unsigned int flags = 0, flags2 = 0, rb_caps;
+    enum wined3d_gl_resource_type gl_type;
+    const struct wined3d_format *format;
+
+    TRACE("device %p, format %s, format_support %p, format_support_2 %p.\n",
+            device, debug_d3dformat(format_id), format_support, format_support_2);
+
+    /* 10level9 exposes no support for DXGI_FORMAT_UNKNOWN. Level 10+ report BUFFER|CPU_LOCKABLE. */
+    if (format_id == WINED3DFMT_UNKNOWN)
+    {
+        if (format_support_2)
+            *format_support_2 = 0;
+        if (d3d_info->feature_level < WINED3D_FEATURE_LEVEL_10)
+        {
+            if (format_support)
+                *format_support = 0;
+            return E_FAIL;
+        }
+        else
+        {
+            if (format_support)
+                *format_support = WINED3D_FORMAT_SUPPORT_SHADER_BUFFER
+                        | WINED3D_FORMAT_SUPPORT_CPU_LOCKABLE;
+            return S_OK;
+        }
+    }
+
+    format = wined3d_get_format(adapter, format_id, 0);
+
+    /* 10level9 has no support for typeless. */
+    if (d3d_info->feature_level < WINED3D_FEATURE_LEVEL_10 && wined3d_format_is_typeless(format))
+    {
+        if (format_support)
+            *format_support = 0;
+        if (format_support_2)
+            *format_support_2 = 0;
+        return E_FAIL;
+    }
+
+    /* Native only allows these formats for an index buffer. */
+    if (format_id == WINED3DFMT_R16_UINT || format_id == WINED3DFMT_R32_UINT)
+        flags |= WINED3D_FORMAT_SUPPORT_IA_INDEX_BUFFER;
+    if (format->caps[WINED3D_GL_RES_TYPE_BUFFER] & WINED3D_FORMAT_CAP_VERTEX_ATTRIBUTE)
+    {
+        flags |= WINED3D_FORMAT_SUPPORT_IA_VERTEX_BUFFER;
+        /* Only types that can be expressed in a stream output buffer go here. */
+        switch (format_id)
+        {
+            case WINED3DFMT_R32_FLOAT:
+            case WINED3DFMT_R32_UINT:
+            case WINED3DFMT_R32_SINT:
+            case WINED3DFMT_R32G32_FLOAT:
+            case WINED3DFMT_R32G32_UINT:
+            case WINED3DFMT_R32G32_SINT:
+            case WINED3DFMT_R32G32B32_FLOAT:
+            case WINED3DFMT_R32G32B32_UINT:
+            case WINED3DFMT_R32G32B32_SINT:
+            case WINED3DFMT_R32G32B32A32_FLOAT:
+            case WINED3DFMT_R32G32B32A32_UINT:
+            case WINED3DFMT_R32G32B32A32_SINT:
+                flags |= WINED3D_FORMAT_SUPPORT_SO_BUFFER;
+                break;
+            default:
+                break;
+        }
+    }
+
+    for (gl_type = WINED3D_GL_RES_TYPE_TEX_1D; gl_type < WINED3D_GL_RES_TYPE_COUNT; ++gl_type)
+    {
+        if (format->caps[gl_type] & WINED3D_FORMAT_CAP_TEXTURE)
+        {
+            switch (gl_type)
+            {
+                case WINED3D_GL_RES_TYPE_TEX_1D:
+                    flags |= WINED3D_FORMAT_SUPPORT_TEXTURE_1D | WINED3D_FORMAT_SUPPORT_MIP;
+                    break;
+                case WINED3D_GL_RES_TYPE_TEX_2D:
+                    flags |= WINED3D_FORMAT_SUPPORT_TEXTURE_2D | WINED3D_FORMAT_SUPPORT_MIP;
+                    break;
+                case WINED3D_GL_RES_TYPE_TEX_RECT:
+                    flags |= WINED3D_FORMAT_SUPPORT_TEXTURE_2D;
+                    break;
+                case WINED3D_GL_RES_TYPE_TEX_3D:
+                    flags |= WINED3D_FORMAT_SUPPORT_TEXTURE_3D | WINED3D_FORMAT_SUPPORT_MIP;
+                    break;
+                case WINED3D_GL_RES_TYPE_TEX_CUBE:
+                    flags |= WINED3D_FORMAT_SUPPORT_TEXTURE_CUBE | WINED3D_FORMAT_SUPPORT_MIP;
+                    break;
+                case WINED3D_GL_RES_TYPE_BUFFER:
+                    if (d3d_info->feature_level >= WINED3D_FEATURE_LEVEL_10)
+                        flags |= WINED3D_FORMAT_SUPPORT_SHADER_BUFFER;
+                    break;
+                default:
+                    break;
+            }
+            if (format->caps[gl_type] & WINED3D_FORMAT_CAP_GEN_MIPMAP)
+                flags |= WINED3D_FORMAT_SUPPORT_MIP_AUTOGEN;
+            /* Only typed RGBA formats can be read from a shader. */
+            if (!wined3d_format_is_typeless(format)
+                    && !(format->caps[gl_type] & WINED3D_FORMAT_CAP_DEPTH_STENCIL))
+            {
+                flags |= WINED3D_FORMAT_SUPPORT_SHADER_LOAD;
+                /* d3d11 requires 4 and 8 sample counts support for formats reported to support multisample. */
+                if (format->multisample_types & 0x88 == 0x88)
+                    flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_LOAD;
+                if (format->caps[gl_type] & WINED3D_FORMAT_CAP_FILTERING)
+                {
+                    flags |= WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE;
+                    if (d3d_info->feature_level >= WINED3D_FEATURE_LEVEL_10_1)
+                        flags |= WINED3D_FORMAT_SUPPORT_SHADER_GATHER;
+                    if (wined3d_format_is_depth_view(format->typeless_id, format_id))
+                    {
+                        flags |= WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON;
+                        if (d3d_info->feature_level >= WINED3D_FEATURE_LEVEL_10_1)
+                            flags |= WINED3D_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON;
+                    }
+                }
+                if (format->caps[gl_type] & WINED3D_FORMAT_CAP_UNORDERED_ACCESS)
+                {
+                    flags |= WINED3D_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW;
+                    flags2 |= WINED3D_FORMAT_SUPPORT2_UAV_TYPED_STORE;
+                }
+            }
+            /* 10level9 doesn't allow mapping depth/stencil surfaces, but level 10+ do. */
+            if (d3d_info->feature_level >= WINED3D_FEATURE_LEVEL_10
+                    || !(format->caps[gl_type] & WINED3D_FORMAT_CAP_DEPTH_STENCIL))
+                flags |= WINED3D_FORMAT_SUPPORT_CPU_LOCKABLE;
+        }
+
+        if ((format->caps[gl_type] & WINED3D_FORMAT_CAP_RENDERTARGET)
+                && adapter->adapter_ops->adapter_check_format(adapter, NULL, format, NULL))
+        {
+            flags |= WINED3D_FORMAT_SUPPORT_RENDER_TARGET;
+            if (format->caps[gl_type] & WINED3D_FORMAT_CAP_POSTPIXELSHADER_BLENDING)
+                flags |= WINED3D_FORMAT_SUPPORT_BLENDABLE;
+            /* d3d11 requires 4 and 8 sample counts support for formats reported to support multisample. */
+            if (format->multisample_types & 0x88 == 0x88)
+                flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RENDER_TARGET
+                        | WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE;
+            /* Only these formats are supported for display. */
+            /* FIXME: This needs an adapter op using the swapchain, or a swapchain op. */
+            switch (format_id)
+            {
+                case WINED3DFMT_R16G16B16A16_FLOAT:
+                case WINED3DFMT_R10G10B10A2_UNORM:
+                case WINED3DFMT_R10G10B10_XR_BIAS_A2_UNORM:
+                case WINED3DFMT_R8G8B8A8_UNORM:
+                case WINED3DFMT_R8G8B8A8_UNORM_SRGB:
+                case WINED3DFMT_B8G8R8A8_UNORM:
+                case WINED3DFMT_B8G8R8A8_UNORM_SRGB:
+                    flags |= WINED3D_FORMAT_SUPPORT_DISPLAY;
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        if ((format->caps[gl_type] & WINED3D_FORMAT_CAP_DEPTH_STENCIL)
+                && adapter->adapter_ops->adapter_check_format(adapter, NULL, NULL, format))
+        {
+            flags |= WINED3D_FORMAT_SUPPORT_DEPTH_STENCIL;
+            /* No depth/stencil formats support multisample resolve. */
+            if (format->multisample_types)
+                flags |= WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RENDER_TARGET;
+        }
+    }
+
+    rb_caps = format->caps[WINED3D_GL_RES_TYPE_TEX_2D] | format->caps[WINED3D_GL_RES_TYPE_RB];
+    if (rb_caps & WINED3D_FORMAT_CAP_BLIT)
+    {
+        flags |= WINED3D_FORMAT_SUPPORT_TEXTURE_2D;
+        if (d3d_info->feature_level >= WINED3D_FEATURE_LEVEL_10 || !(rb_caps & WINED3D_FORMAT_CAP_DEPTH_STENCIL))
+            flags |= WINED3D_FORMAT_SUPPORT_CPU_LOCKABLE;
+    }
+
+    if (adapter->d3d_info.feature_level >= WINED3D_FEATURE_LEVEL_10
+            && format->typeless_id != WINED3DFMT_UNKNOWN)
+        flags |= WINED3D_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT;
+
+    if (format_support)
+        *format_support = flags;
+    if (format_support_2)
+        *format_support_2 = flags2;
+
+    return !(flags || flags2) ? E_FAIL : S_OK;
+}
+
 HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, struct wined3d_caps *caps)
 {
     TRACE("device %p, caps %p.\n", device, caps);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 63220e1222c..8a3cd7b325f 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -51,6 +51,7 @@
 @ cdecl wined3d_device_acquire_focus_window(ptr ptr)
 @ cdecl wined3d_device_apply_stateblock(ptr ptr)
 @ cdecl wined3d_device_begin_scene(ptr)
+@ cdecl wined3d_device_check_format_support(ptr long ptr ptr)
 @ cdecl wined3d_device_clear(ptr long ptr long ptr float long)
 @ cdecl wined3d_device_create(ptr ptr long ptr long long ptr long ptr ptr)
 @ cdecl wined3d_device_decref(ptr)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 116aea82348..c0aa59df4ee 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1335,6 +1335,52 @@ enum wined3d_memory_segment_group
 #define WINED3DDEVCAPS_RTPATCHHANDLEZERO                        0x00800000
 #define WINED3DDEVCAPS_NPATCHES                                 0x01000000
 
+#define WINED3D_FORMAT_SUPPORT_SHADER_BUFFER                    0x00000001
+#define WINED3D_FORMAT_SUPPORT_IA_VERTEX_BUFFER                 0x00000002
+#define WINED3D_FORMAT_SUPPORT_IA_INDEX_BUFFER                  0x00000004
+#define WINED3D_FORMAT_SUPPORT_SO_BUFFER                        0x00000008
+#define WINED3D_FORMAT_SUPPORT_TEXTURE_1D                       0x00000010
+#define WINED3D_FORMAT_SUPPORT_TEXTURE_2D                       0x00000020
+#define WINED3D_FORMAT_SUPPORT_TEXTURE_3D                       0x00000040
+#define WINED3D_FORMAT_SUPPORT_TEXTURE_CUBE                     0x00000080
+#define WINED3D_FORMAT_SUPPORT_SHADER_LOAD                      0x00000100
+#define WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE                    0x00000200
+#define WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON         0x00000400
+#define WINED3D_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT          0x00000800
+#define WINED3D_FORMAT_SUPPORT_MIP                              0x00001000
+#define WINED3D_FORMAT_SUPPORT_MIP_AUTOGEN                      0x00002000
+#define WINED3D_FORMAT_SUPPORT_RENDER_TARGET                    0x00004000
+#define WINED3D_FORMAT_SUPPORT_BLENDABLE                        0x00008000
+#define WINED3D_FORMAT_SUPPORT_DEPTH_STENCIL                    0x00010000
+#define WINED3D_FORMAT_SUPPORT_CPU_LOCKABLE                     0x00020000
+#define WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE              0x00040000
+#define WINED3D_FORMAT_SUPPORT_DISPLAY                          0x00080000
+#define WINED3D_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT           0x00100000
+#define WINED3D_FORMAT_SUPPORT_MULTISAMPLE_RENDER_TARGET        0x00200000
+#define WINED3D_FORMAT_SUPPORT_MULTISAMPLE_LOAD                 0x00400000
+#define WINED3D_FORMAT_SUPPORT_SHADER_GATHER                    0x00800000
+#define WINED3D_FORMAT_SUPPORT_BACK_BUFFER_CAST                 0x01000000
+#define WINED3D_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW      0x02000000
+#define WINED3D_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON         0x04000000
+#define WINED3D_FORMAT_SUPPORT_DECODER_OUTPUT                   0x08000000
+#define WINED3D_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT           0x10000000
+#define WINED3D_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT            0x20000000
+#define WINED3D_FORMAT_SUPPORT_VIDEO_ENCODER                    0x40000000
+
+#define WINED3D_FORMAT_SUPPORT2_UAV_ATOMIC_ADD                  0x00000001
+#define WINED3D_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS          0x00000002
+#define WINED3D_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_XCHG   0x00000004
+#define WINED3D_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE             0x00000008
+#define WINED3D_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_MAX       0x00000010
+#define WINED3D_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_MAX     0x00000020
+#define WINED3D_FORMAT_SUPPORT2_UAV_TYPED_LOAD                  0x00000040
+#define WINED3D_FORMAT_SUPPORT2_UAV_TYPED_STORE                 0x00000080
+#define WINED3D_FORMAT_SUPPORT2_OM_LOGIC_OP                     0x00000100
+#define WINED3D_FORMAT_SUPPORT2_TILED                           0x00000200
+#define WINED3D_FORMAT_SUPPORT2_SHAREABLE                       0x00000400
+
+#define WINED3D_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY              0x00004000
+
 #define WINED3D_LEGACY_DEPTH_BIAS                               0x00000001
 #define WINED3D_NO3D                                            0x00000002
 #define WINED3D_VIDMEM_ACCOUNTING                               0x00000004
@@ -2394,6 +2440,9 @@ ULONG __cdecl wined3d_depth_stencil_state_incref(struct wined3d_depth_stencil_st
 HRESULT __cdecl wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window);
 void __cdecl wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_stateblock *stateblock);
 HRESULT __cdecl wined3d_device_begin_scene(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_check_format_support(const struct wined3d_device *device,
+        enum wined3d_format_id format_id, unsigned int *format_support,
+        unsigned int *format_support_2);
 HRESULT __cdecl wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, const RECT *rects, DWORD flags,
         const struct wined3d_color *color, float z, DWORD stencil);
 HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, struct wined3d_adapter *adapter,
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/131



More information about the wine-devel mailing list