From 385d06daa5f3ebba64b6958de26dc2a05c360c70 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 1 May 2020 15:06:20 +0430 Subject: [PATCH] wined3d: Create Vulkan samplers for samplers. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- 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); - wined3d_cs_destroy_object(sampler->device->cs, heap_free, sampler); + TRACE("sampler_vk %p.\n", sampler_vk); + + 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;