[PATCH 1/5] wined3d: Create Vulkan samplers for samplers.

Henri Verbeet hverbeet at codeweavers.com
Fri May 1 05:36:20 CDT 2020


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/adapter_vk.c      |  23 +++++--
 dlls/wined3d/context_vk.c      |  59 +++++++++++++++++
 dlls/wined3d/sampler.c         | 115 ++++++++++++++++++++++++++++++++-
 dlls/wined3d/wined3d_private.h |  20 +++++-
 4 files changed, 210 insertions(+), 7 deletions(-)

diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index bd943a65afb..65850ab4ccc 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1439,7 +1439,7 @@ static void adapter_vk_destroy_unordered_access_view(struct wined3d_unordered_ac
 static HRESULT adapter_vk_create_sampler(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler)
 {
-    struct wined3d_sampler *sampler_vk;
+    struct wined3d_sampler_vk *sampler_vk;
 
     TRACE("device %p, desc %p, parent %p, parent_ops %p, sampler %p.\n",
             device, desc, parent, parent_ops, sampler);
@@ -1450,16 +1450,31 @@ static HRESULT adapter_vk_create_sampler(struct wined3d_device *device, const st
     wined3d_sampler_vk_init(sampler_vk, device, desc, parent, parent_ops);
 
     TRACE("Created sampler %p.\n", sampler_vk);
-    *sampler = sampler_vk;
+    *sampler = &sampler_vk->s;
 
     return WINED3D_OK;
 }
 
+static void wined3d_sampler_vk_destroy_object(void *object)
+{
+    struct wined3d_sampler_vk *sampler_vk = object;
+    struct wined3d_context_vk *context_vk;
+
+    context_vk = wined3d_context_vk(context_acquire(sampler_vk->s.device, NULL, 0));
+
+    wined3d_context_vk_destroy_sampler(context_vk, sampler_vk->vk_image_info.sampler, sampler_vk->command_buffer_id);
+    heap_free(sampler_vk);
+
+    context_release(&context_vk->c);
+}
+
 static void adapter_vk_destroy_sampler(struct wined3d_sampler *sampler)
 {
-    TRACE("sampler %p.\n", sampler);
+    struct wined3d_sampler_vk *sampler_vk = wined3d_sampler_vk(sampler);
+
+    TRACE("sampler_vk %p.\n", sampler_vk);
 
-    wined3d_cs_destroy_object(sampler->device->cs, heap_free, sampler);
+    wined3d_cs_destroy_object(sampler->device->cs, wined3d_sampler_vk_destroy_object, sampler_vk);
 }
 
 static HRESULT adapter_vk_create_query(struct wined3d_device *device, enum wined3d_query_type type,
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 35b2b7eb7c7..20a0df181ca 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -29,6 +29,35 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
+VkCompareOp vk_compare_op_from_wined3d(enum wined3d_cmp_func op)
+{
+    switch (op)
+    {
+        case WINED3D_CMP_NEVER:
+            return VK_COMPARE_OP_NEVER;
+        case WINED3D_CMP_LESS:
+            return VK_COMPARE_OP_LESS;
+        case WINED3D_CMP_EQUAL:
+            return VK_COMPARE_OP_EQUAL;
+        case WINED3D_CMP_LESSEQUAL:
+            return VK_COMPARE_OP_LESS_OR_EQUAL;
+        case WINED3D_CMP_GREATER:
+            return VK_COMPARE_OP_GREATER;
+        case WINED3D_CMP_NOTEQUAL:
+            return VK_COMPARE_OP_NOT_EQUAL;
+        case WINED3D_CMP_GREATEREQUAL:
+            return VK_COMPARE_OP_GREATER_OR_EQUAL;
+        case WINED3D_CMP_ALWAYS:
+            return VK_COMPARE_OP_ALWAYS;
+        default:
+            if (!op)
+                WARN("Unhandled compare operation %#x.\n", op);
+            else
+                FIXME("Unhandled compare operation %#x.\n", op);
+            return VK_COMPARE_OP_NEVER;
+    }
+}
+
 void *wined3d_allocator_chunk_vk_map(struct wined3d_allocator_chunk_vk *chunk_vk,
         struct wined3d_context_vk *context_vk)
 {
@@ -519,6 +548,31 @@ void wined3d_context_vk_destroy_image_view(struct wined3d_context_vk *context_vk
     o->command_buffer_id = command_buffer_id;
 }
 
+void wined3d_context_vk_destroy_sampler(struct wined3d_context_vk *context_vk,
+        VkSampler vk_sampler, uint64_t command_buffer_id)
+{
+    struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+    const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+    struct wined3d_retired_object_vk *o;
+
+    if (context_vk->completed_command_buffer_id > command_buffer_id)
+    {
+        VK_CALL(vkDestroySampler(device_vk->vk_device, vk_sampler, NULL));
+        TRACE("Destroyed sampler 0x%s.\n", wine_dbgstr_longlong(vk_sampler));
+        return;
+    }
+
+    if (!(o = wined3d_context_vk_get_retired_object_vk(context_vk)))
+    {
+        ERR("Leaking sampler 0x%s.\n", wine_dbgstr_longlong(vk_sampler));
+        return;
+    }
+
+    o->type = WINED3D_RETIRED_SAMPLER_VK;
+    o->u.vk_sampler = vk_sampler;
+    o->command_buffer_id = command_buffer_id;
+}
+
 void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const struct wined3d_bo_vk *bo)
 {
     size_t object_size, idx;
@@ -627,6 +681,11 @@ static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *cont
                 TRACE("Destroyed image view 0x%s.\n", wine_dbgstr_longlong(o->u.vk_image_view));
                 break;
 
+            case WINED3D_RETIRED_SAMPLER_VK:
+                VK_CALL(vkDestroySampler(device_vk->vk_device, o->u.vk_sampler, NULL));
+                TRACE("Destroyed sampler 0x%s.\n", wine_dbgstr_longlong(o->u.vk_sampler));
+                break;
+
             default:
                 ERR("Unhandled object type %#x.\n", o->type);
                 break;
diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c
index c4f4d3eec30..8d909627a18 100644
--- a/dlls/wined3d/sampler.c
+++ b/dlls/wined3d/sampler.c
@@ -124,13 +124,124 @@ void wined3d_sampler_gl_init(struct wined3d_sampler_gl *sampler_gl, struct wined
         wined3d_cs_init_object(device->cs, wined3d_sampler_gl_cs_init, sampler_gl);
 }
 
-void wined3d_sampler_vk_init(struct wined3d_sampler *sampler_vk, struct wined3d_device *device,
+static VkFilter vk_filter_from_wined3d(enum wined3d_texture_filter_type f)
+{
+    switch (f)
+    {
+        default:
+            ERR("Invalid filter type %#x.\n", f);
+        case WINED3D_TEXF_POINT:
+            return VK_FILTER_NEAREST;
+        case WINED3D_TEXF_LINEAR:
+            return VK_FILTER_LINEAR;
+    }
+}
+
+static VkSamplerMipmapMode vk_mipmap_mode_from_wined3d(enum wined3d_texture_filter_type f)
+{
+    switch (f)
+    {
+        default:
+            ERR("Invalid filter type %#x.\n", f);
+        case WINED3D_TEXF_NONE:
+        case WINED3D_TEXF_POINT:
+            return VK_SAMPLER_MIPMAP_MODE_NEAREST;
+        case WINED3D_TEXF_LINEAR:
+            return VK_SAMPLER_MIPMAP_MODE_LINEAR;
+    }
+}
+
+static VkSamplerAddressMode vk_address_mode_from_wined3d(enum wined3d_texture_address a)
+{
+    switch (a)
+    {
+        default:
+            ERR("Invalid address mode %#x.\n", a);
+        case WINED3D_TADDRESS_WRAP:
+            return VK_SAMPLER_ADDRESS_MODE_REPEAT;
+        case WINED3D_TADDRESS_MIRROR:
+            return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
+        case WINED3D_TADDRESS_CLAMP:
+            return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+        case WINED3D_TADDRESS_BORDER:
+            return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
+        case WINED3D_TADDRESS_MIRROR_ONCE:
+            return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
+    }
+}
+
+static void wined3d_sampler_vk_cs_init(void *object)
+{
+    struct wined3d_sampler_vk *sampler_vk = object;
+    const struct wined3d_sampler_desc *desc;
+    const struct wined3d_d3d_info *d3d_info;
+    struct VkSamplerCreateInfo sampler_desc;
+    const struct wined3d_vk_info *vk_info;
+    struct wined3d_context_vk *context_vk;
+    struct wined3d_device_vk *device_vk;
+    VkSampler vk_sampler;
+    VkResult vr;
+
+    context_vk = wined3d_context_vk(context_acquire(sampler_vk->s.device, NULL, 0));
+    device_vk = wined3d_device_vk(context_vk->c.device);
+    d3d_info = context_vk->c.d3d_info;
+    vk_info = context_vk->vk_info;
+
+    desc = &sampler_vk->s.desc;
+    sampler_desc.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+    sampler_desc.pNext = NULL;
+    sampler_desc.flags = 0;
+    sampler_desc.magFilter = vk_filter_from_wined3d(desc->mag_filter);
+    sampler_desc.minFilter = vk_filter_from_wined3d(desc->min_filter);
+    sampler_desc.mipmapMode = vk_mipmap_mode_from_wined3d(desc->mip_filter);
+    sampler_desc.addressModeU = vk_address_mode_from_wined3d(desc->address_u);
+    sampler_desc.addressModeV = vk_address_mode_from_wined3d(desc->address_v);
+    sampler_desc.addressModeW = vk_address_mode_from_wined3d(desc->address_w);
+    sampler_desc.mipLodBias = desc->lod_bias;
+    sampler_desc.anisotropyEnable = desc->max_anisotropy != 1;
+    sampler_desc.maxAnisotropy = desc->max_anisotropy;
+    sampler_desc.compareEnable = desc->compare;
+    sampler_desc.compareOp = vk_compare_op_from_wined3d(desc->comparison_func);
+    sampler_desc.minLod = desc->min_lod;
+    sampler_desc.maxLod = desc->max_lod;
+    sampler_desc.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
+    sampler_desc.unnormalizedCoordinates = VK_FALSE;
+
+    if ((desc->address_u == WINED3D_TADDRESS_BORDER || desc->address_v == WINED3D_TADDRESS_BORDER
+            || desc->address_w == WINED3D_TADDRESS_BORDER)
+            && (desc->border_color[0] != 0.0f || desc->border_color[1] != 0.0f
+            || desc->border_color[2] != 0.0f || desc->border_color[3] != 0.0f))
+        FIXME("Unhandled border colour {%.8e, %.8e, %.8e, %.8e}.\n",
+                desc->border_color[0], desc->border_color[1],
+                desc->border_color[2], desc->border_color[3]);
+    if (desc->mip_base_level)
+        FIXME("Unhandled mip_base_level %u.\n", desc->mip_base_level);
+    if ((d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) && !desc->srgb_decode)
+        FIXME("Unhandled srgb_decode %#x.\n", desc->srgb_decode);
+
+    vr = VK_CALL(vkCreateSampler(device_vk->vk_device, &sampler_desc, NULL, &vk_sampler));
+    context_release(&context_vk->c);
+    if (vr < 0)
+    {
+        ERR("Failed to create Vulkan sampler, vr %s.\n", wined3d_debug_vkresult(vr));
+        return;
+    }
+
+    TRACE("Created sampler 0x%s.\n", wine_dbgstr_longlong(vk_sampler));
+
+    sampler_vk->vk_image_info.sampler = vk_sampler;
+    sampler_vk->vk_image_info.imageView = VK_NULL_HANDLE;
+    sampler_vk->vk_image_info.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+}
+
+void wined3d_sampler_vk_init(struct wined3d_sampler_vk *sampler_vk, struct wined3d_device *device,
         const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
 {
     TRACE("sampler_vk %p, device %p, desc %p, parent %p, parent_ops %p.\n",
             sampler_vk, device, desc, parent, parent_ops);
 
-    wined3d_sampler_init(sampler_vk, device, desc, parent, parent_ops);
+    wined3d_sampler_init(&sampler_vk->s, device, desc, parent, parent_ops);
+    wined3d_cs_init_object(device->cs, wined3d_sampler_vk_cs_init, sampler_vk);
 }
 
 HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2409728f270..7a412d7a8e7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -300,6 +300,7 @@ extern const GLenum magLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
 
 GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f) DECLSPEC_HIDDEN;
 VkAccessFlags vk_access_mask_from_bind_flags(uint32_t bind_flags) DECLSPEC_HIDDEN;
+VkCompareOp vk_compare_op_from_wined3d(enum wined3d_cmp_func op) DECLSPEC_HIDDEN;
 VkImageViewType vk_image_view_type_from_wined3d(enum wined3d_resource_type type, uint32_t flags) DECLSPEC_HIDDEN;
 
 static inline enum wined3d_cmp_func wined3d_sanitize_cmp_func(enum wined3d_cmp_func func)
@@ -2232,6 +2233,7 @@ enum wined3d_retired_object_type_vk
     WINED3D_RETIRED_IMAGE_VK,
     WINED3D_RETIRED_BUFFER_VIEW_VK,
     WINED3D_RETIRED_IMAGE_VIEW_VK,
+    WINED3D_RETIRED_SAMPLER_VK,
 };
 
 struct wined3d_retired_object_vk
@@ -2252,6 +2254,7 @@ struct wined3d_retired_object_vk
         VkImage vk_image;
         VkBufferView vk_buffer_view;
         VkImageView vk_image_view;
+        VkSampler vk_sampler;
     } u;
     uint64_t command_buffer_id;
 };
@@ -2334,6 +2337,8 @@ void wined3d_context_vk_destroy_image_view(struct wined3d_context_vk *context_vk
         VkImageView vk_view, uint64_t command_buffer_id) DECLSPEC_HIDDEN;
 void wined3d_context_vk_destroy_memory(struct wined3d_context_vk *context_vk,
         VkDeviceMemory vk_memory, uint64_t command_buffer_id) DECLSPEC_HIDDEN;
+void wined3d_context_vk_destroy_sampler(struct wined3d_context_vk *context_vk,
+        VkSampler vk_sampler, uint64_t command_buffer_id) DECLSPEC_HIDDEN;
 VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
 VkRenderPass wined3d_context_vk_get_render_pass(struct wined3d_context_vk *context_vk,
         const struct wined3d_fb_state *fb, unsigned int rt_count,
@@ -4113,7 +4118,20 @@ void wined3d_sampler_gl_init(struct wined3d_sampler_gl *sampler_gl,
         struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
         void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
 
-void wined3d_sampler_vk_init(struct wined3d_sampler *sampler_vk,
+struct wined3d_sampler_vk
+{
+    struct wined3d_sampler s;
+
+    VkDescriptorImageInfo vk_image_info;
+    uint64_t command_buffer_id;
+};
+
+static inline struct wined3d_sampler_vk *wined3d_sampler_vk(struct wined3d_sampler *sampler)
+{
+    return CONTAINING_RECORD(sampler, struct wined3d_sampler_vk, s);
+}
+
+void wined3d_sampler_vk_init(struct wined3d_sampler_vk *sampler_vk,
         struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
         void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
 
-- 
2.20.1




More information about the wine-devel mailing list