Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/adapter_vk.c | 4 ++ dlls/wined3d/context_vk.c | 27 ++++++++++- dlls/wined3d/device.c | 85 ++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 23 +++++++++ 4 files changed, 137 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 4dbbb0b80ef..cf82d00e40b 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -678,6 +678,8 @@ static HRESULT adapter_vk_init_3d(struct wined3d_device *device) wined3d_vk_blitter_create(&device_vk->d.blitter);
wined3d_device_create_default_samplers(device, &context_vk->c); + wined3d_device_vk_create_null_resources(device_vk, context_vk); + wined3d_device_vk_create_null_views(device_vk, context_vk);
return WINED3D_OK; } @@ -701,6 +703,8 @@ static void adapter_vk_uninit_3d_cs(void *object)
device->blitter->ops->blitter_destroy(device->blitter, NULL); device->shader_backend->shader_free_private(device, &context_vk->c); + wined3d_device_vk_destroy_null_views(device_vk, context_vk); + wined3d_device_vk_destroy_null_resources(device_vk, context_vk); wined3d_device_destroy_default_samplers(device, &context_vk->c); }
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 2f170b085ba..0199b655dff 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1321,6 +1321,27 @@ static bool wined3d_shader_descriptor_writes_vk_add_write(struct wined3d_shader_ return true; }
+static bool wined3d_shader_resource_bindings_add_null_srv_binding(struct wined3d_shader_descriptor_writes_vk *writes, + VkDescriptorSet vk_descriptor_set, size_t binding_idx, enum wined3d_shader_resource_type type, + enum wined3d_data_type data_type, struct wined3d_context_vk *context_vk) +{ + const struct wined3d_null_views_vk *v = &wined3d_device_vk(context_vk->c.device)->null_views_vk; + + switch (type) + { + case WINED3D_SHADER_RESOURCE_BUFFER: + if (data_type == WINED3D_DATA_FLOAT) + return wined3d_shader_descriptor_writes_vk_add_write(writes, vk_descriptor_set, binding_idx, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, NULL, NULL, &v->vk_view_buffer_float); + return wined3d_shader_descriptor_writes_vk_add_write(writes, vk_descriptor_set, binding_idx, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, NULL, NULL, &v->vk_view_buffer_uint); + + default: + FIXME("Unhandled resource type %#x.\n", type); + return false; + } +} + static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer, const struct wined3d_state *state) { @@ -1374,8 +1395,10 @@ static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *con case WINED3D_SHADER_DESCRIPTOR_TYPE_SRV: if (!(srv = state->shader_resource_view[binding->shader_type][binding->resource_idx])) { - FIXME("NULL shader resource views not implemented.\n"); - return false; + if (!wined3d_shader_resource_bindings_add_null_srv_binding(writes, vk_descriptor_set, + binding->binding_idx, binding->resource_type, binding->resource_data_type, context_vk)) + return false; + break; } resource = srv->resource;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index cc13ab4863e..081001e487e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -655,6 +655,91 @@ void wined3d_device_destroy_default_samplers(struct wined3d_device *device, stru device->null_sampler = NULL; }
+bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk, + struct wined3d_context_vk *context_vk) +{ + struct wined3d_null_resources_vk *r = &device_vk->null_resources_vk; + const struct wined3d_vk_info *vk_info; + VkMemoryPropertyFlags memory_type; + VkCommandBuffer vk_command_buffer; + VkBufferUsageFlags usage; + + if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk))) + { + ERR("Failed to get command buffer.\n"); + return false; + } + + vk_info = context_vk->vk_info; + + usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; + memory_type = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + if (!wined3d_context_vk_create_bo(context_vk, 16, usage, memory_type, &r->bo)) + return false; + VK_CALL(vkCmdFillBuffer(vk_command_buffer, r->bo.vk_buffer, r->bo.buffer_offset, r->bo.size, 0x00000000u)); + + return true; +} + +void wined3d_device_vk_destroy_null_resources(struct wined3d_device_vk *device_vk, + struct wined3d_context_vk *context_vk) +{ + struct wined3d_null_resources_vk *r = &device_vk->null_resources_vk; + + /* We don't track command buffer references to NULL resources. We easily + * could, but it doesn't seem worth it. */ + wined3d_context_vk_reference_bo(context_vk, &r->bo); + wined3d_context_vk_destroy_bo(context_vk, &r->bo); +} + +bool wined3d_device_vk_create_null_views(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk) +{ + struct wined3d_null_resources_vk *r = &device_vk->null_resources_vk; + struct wined3d_null_views_vk *v = &device_vk->null_views_vk; + VkBufferViewCreateInfo buffer_create_info; + const struct wined3d_vk_info *vk_info; + VkResult vr; + + vk_info = context_vk->vk_info; + + buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; + buffer_create_info.pNext = NULL; + buffer_create_info.flags = 0; + buffer_create_info.buffer = r->bo.vk_buffer; + buffer_create_info.format = VK_FORMAT_R32_UINT; + buffer_create_info.offset = r->bo.buffer_offset;; + buffer_create_info.range = r->bo.size; + + if ((vr = VK_CALL(vkCreateBufferView(device_vk->vk_device, + &buffer_create_info, NULL, &v->vk_view_buffer_uint))) < 0) + { + ERR("Failed to create buffer view, vr %s.\n", wined3d_debug_vkresult(vr)); + return false; + } + TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(v->vk_view_buffer_uint)); + + buffer_create_info.format = VK_FORMAT_R32G32B32A32_SFLOAT; + if ((vr = VK_CALL(vkCreateBufferView(device_vk->vk_device, + &buffer_create_info, NULL, &v->vk_view_buffer_float))) < 0) + { + ERR("Failed to create buffer view, vr %s.\n", wined3d_debug_vkresult(vr)); + VK_CALL(vkDestroyBufferView(device_vk->vk_device, v->vk_view_buffer_uint, NULL)); + return false; + } + TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(v->vk_view_buffer_float)); + + return true; +} + +void wined3d_device_vk_destroy_null_views(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk) +{ + struct wined3d_null_views_vk *v = &device_vk->null_views_vk; + uint64_t id = context_vk->current_command_buffer.id; + + wined3d_context_vk_destroy_buffer_view(context_vk, v->vk_view_buffer_float, id); + wined3d_context_vk_destroy_buffer_view(context_vk, v->vk_view_buffer_uint, id); +} + HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window) { unsigned int screensaver_active; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d9e8ffa816f..3d2273b9f63 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3607,6 +3607,17 @@ static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device return CONTAINING_RECORD(device, struct wined3d_device_gl, d); }
+struct wined3d_null_resources_vk +{ + struct wined3d_bo_vk bo; +}; + +struct wined3d_null_views_vk +{ + VkBufferView vk_view_buffer_uint; + VkBufferView vk_view_buffer_float; +}; + #define WINED3D_ALLOCATOR_CHUNK_SIZE (64 * 1024 * 1024) #define WINED3D_ALLOCATOR_CHUNK_ORDER_COUNT 15 #define WINED3D_ALLOCATOR_MIN_BLOCK_SIZE (WINED3D_ALLOCATOR_CHUNK_SIZE >> (WINED3D_ALLOCATOR_CHUNK_ORDER_COUNT - 1)) @@ -3691,6 +3702,9 @@ struct wined3d_device_vk
struct wined3d_vk_info vk_info;
+ struct wined3d_null_resources_vk null_resources_vk; + struct wined3d_null_views_vk null_views_vk; + struct wined3d_allocator allocator; };
@@ -3699,6 +3713,15 @@ static inline struct wined3d_device_vk *wined3d_device_vk(struct wined3d_device return CONTAINING_RECORD(device, struct wined3d_device_vk, d); }
+bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk, + struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; +bool wined3d_device_vk_create_null_views(struct wined3d_device_vk *device_vk, + struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; +void wined3d_device_vk_destroy_null_resources(struct wined3d_device_vk *device_vk, + struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; +void wined3d_device_vk_destroy_null_views(struct wined3d_device_vk *device_vk, + struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; + static inline float wined3d_alpha_ref(const struct wined3d_state *state) { return (state->render_states[WINED3D_RS_ALPHAREF] & 0xff) / 255.0f;