wined3d: Implement Vulkan constant buffer descriptors.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9049104df2
commit
9b9bde8d82
|
@ -810,6 +810,7 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
|
||||||
{
|
{
|
||||||
struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
|
struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
|
||||||
const struct wined3d_vk_info *vk_info;
|
const struct wined3d_vk_info *vk_info;
|
||||||
|
struct wined3d_bo_user_vk *bo_user_vk;
|
||||||
struct wined3d_device_vk *device_vk;
|
struct wined3d_device_vk *device_vk;
|
||||||
VkCommandBuffer vk_command_buffer;
|
VkCommandBuffer vk_command_buffer;
|
||||||
VkBufferMemoryBarrier vk_barrier;
|
VkBufferMemoryBarrier vk_barrier;
|
||||||
|
@ -830,8 +831,15 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
|
||||||
{
|
{
|
||||||
if (wined3d_context_vk_create_bo(context_vk, bo->size, bo->usage, bo->memory_type, &tmp))
|
if (wined3d_context_vk_create_bo(context_vk, bo->size, bo->usage, bo->memory_type, &tmp))
|
||||||
{
|
{
|
||||||
|
list_move_head(&tmp.users, &bo->users);
|
||||||
wined3d_context_vk_destroy_bo(context_vk, bo);
|
wined3d_context_vk_destroy_bo(context_vk, bo);
|
||||||
*bo = tmp;
|
*bo = tmp;
|
||||||
|
list_init(&bo->users);
|
||||||
|
list_move_head(&bo->users, &tmp.users);
|
||||||
|
LIST_FOR_EACH_ENTRY(bo_user_vk, &bo->users, struct wined3d_bo_user_vk, entry)
|
||||||
|
{
|
||||||
|
bo_user_vk->valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
goto map;
|
goto map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1593,12 +1593,27 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_init(&buffer_vk->bo_user.entry);
|
||||||
|
list_add_head(&buffer_vk->bo.users, &buffer_vk->bo_user.entry);
|
||||||
buffer_vk->b.buffer_object = (uintptr_t)&buffer_vk->bo;
|
buffer_vk->b.buffer_object = (uintptr_t)&buffer_vk->bo;
|
||||||
buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
|
buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk)
|
||||||
|
{
|
||||||
|
if (buffer_vk->bo_user.valid)
|
||||||
|
return &buffer_vk->buffer_info;
|
||||||
|
|
||||||
|
buffer_vk->buffer_info.buffer = buffer_vk->bo.vk_buffer;
|
||||||
|
buffer_vk->buffer_info.offset = buffer_vk->bo.buffer_offset;
|
||||||
|
buffer_vk->buffer_info.range = buffer_vk->b.resource.size;
|
||||||
|
buffer_vk->bo_user.valid = true;
|
||||||
|
|
||||||
|
return &buffer_vk->buffer_info;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
|
static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
|
||||||
struct wined3d_context *context, unsigned int location)
|
struct wined3d_context *context, unsigned int location)
|
||||||
{
|
{
|
||||||
|
@ -1630,6 +1645,8 @@ static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer,
|
||||||
switch (location)
|
switch (location)
|
||||||
{
|
{
|
||||||
case WINED3D_LOCATION_BUFFER:
|
case WINED3D_LOCATION_BUFFER:
|
||||||
|
buffer_vk->bo_user.valid = false;
|
||||||
|
list_remove(&buffer_vk->bo_user.entry);
|
||||||
wined3d_context_vk_destroy_bo(context_vk, &buffer_vk->bo);
|
wined3d_context_vk_destroy_bo(context_vk, &buffer_vk->bo);
|
||||||
buffer_vk->bo.vk_buffer = VK_NULL_HANDLE;
|
buffer_vk->bo.vk_buffer = VK_NULL_HANDLE;
|
||||||
buffer_vk->bo.memory = NULL;
|
buffer_vk->bo.memory = NULL;
|
||||||
|
|
|
@ -243,6 +243,7 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
|
||||||
bo->buffer_offset = idx * object_size;
|
bo->buffer_offset = idx * object_size;
|
||||||
bo->memory_offset = slab->bo.memory_offset + bo->buffer_offset;
|
bo->memory_offset = slab->bo.memory_offset + bo->buffer_offset;
|
||||||
bo->size = size;
|
bo->size = size;
|
||||||
|
list_init(&bo->users);
|
||||||
bo->command_buffer_id = 0;
|
bo->command_buffer_id = 0;
|
||||||
|
|
||||||
TRACE("Using buffer 0x%s, memory 0x%s, offset 0x%s for bo %p.\n",
|
TRACE("Using buffer 0x%s, memory 0x%s, offset 0x%s for bo %p.\n",
|
||||||
|
@ -319,6 +320,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic
|
||||||
bo->size = size;
|
bo->size = size;
|
||||||
bo->usage = usage;
|
bo->usage = usage;
|
||||||
bo->memory_type = adapter_vk->memory_properties.memoryTypes[memory_type_idx].propertyFlags;
|
bo->memory_type = adapter_vk->memory_properties.memoryTypes[memory_type_idx].propertyFlags;
|
||||||
|
list_init(&bo->users);
|
||||||
bo->command_buffer_id = 0;
|
bo->command_buffer_id = 0;
|
||||||
bo->slab = NULL;
|
bo->slab = NULL;
|
||||||
|
|
||||||
|
@ -770,6 +772,23 @@ static void wined3d_context_vk_destroy_bo_slab(struct wine_rb_entry *entry, void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wined3d_context_vk_destroy_pipeline_layout(struct wine_rb_entry *entry, void *ctx)
|
||||||
|
{
|
||||||
|
struct wined3d_pipeline_layout_vk *layout = WINE_RB_ENTRY_VALUE(entry,
|
||||||
|
struct wined3d_pipeline_layout_vk, entry);
|
||||||
|
struct wined3d_context_vk *context_vk = ctx;
|
||||||
|
const struct wined3d_vk_info *vk_info;
|
||||||
|
struct wined3d_device_vk *device_vk;
|
||||||
|
|
||||||
|
vk_info = context_vk->vk_info;
|
||||||
|
device_vk = wined3d_device_vk(context_vk->c.device);
|
||||||
|
|
||||||
|
VK_CALL(vkDestroyPipelineLayout(device_vk->vk_device, layout->vk_pipeline_layout, NULL));
|
||||||
|
VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, layout->vk_set_layout, NULL));
|
||||||
|
heap_free(layout->key.bindings);
|
||||||
|
heap_free(layout);
|
||||||
|
}
|
||||||
|
|
||||||
static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk *key,
|
static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk *key,
|
||||||
const struct wined3d_fb_state *fb, unsigned int rt_count, bool depth_stencil, uint32_t clear_flags)
|
const struct wined3d_fb_state *fb, unsigned int rt_count, bool depth_stencil, uint32_t clear_flags)
|
||||||
{
|
{
|
||||||
|
@ -966,6 +985,11 @@ static void wined3d_context_vk_destroy_render_pass(struct wine_rb_entry *entry,
|
||||||
heap_free(pass);
|
heap_free(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wined3d_shader_descriptor_writes_vk_cleanup(struct wined3d_shader_descriptor_writes_vk *writes)
|
||||||
|
{
|
||||||
|
heap_free(writes->writes);
|
||||||
|
}
|
||||||
|
|
||||||
void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
|
void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
|
||||||
{
|
{
|
||||||
struct wined3d_command_buffer_vk *buffer = &context_vk->current_command_buffer;
|
struct wined3d_command_buffer_vk *buffer = &context_vk->current_command_buffer;
|
||||||
|
@ -983,11 +1007,6 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
|
||||||
wined3d_context_vk_wait_command_buffer(context_vk, buffer->id - 1);
|
wined3d_context_vk_wait_command_buffer(context_vk, buffer->id - 1);
|
||||||
context_vk->completed_command_buffer_id = buffer->id;
|
context_vk->completed_command_buffer_id = buffer->id;
|
||||||
|
|
||||||
if (context_vk->vk_pipeline_layout)
|
|
||||||
{
|
|
||||||
VK_CALL(vkDestroyPipelineLayout(device_vk->vk_device, context_vk->vk_pipeline_layout, NULL));
|
|
||||||
VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, context_vk->vk_set_layout, NULL));
|
|
||||||
}
|
|
||||||
heap_free(context_vk->compute.bindings.bindings);
|
heap_free(context_vk->compute.bindings.bindings);
|
||||||
if (context_vk->vk_descriptor_pool)
|
if (context_vk->vk_descriptor_pool)
|
||||||
VK_CALL(vkDestroyDescriptorPool(device_vk->vk_device, context_vk->vk_descriptor_pool, NULL));
|
VK_CALL(vkDestroyDescriptorPool(device_vk->vk_device, context_vk->vk_descriptor_pool, NULL));
|
||||||
|
@ -996,6 +1015,8 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
|
||||||
heap_free(context_vk->submitted.buffers);
|
heap_free(context_vk->submitted.buffers);
|
||||||
heap_free(context_vk->retired.objects);
|
heap_free(context_vk->retired.objects);
|
||||||
|
|
||||||
|
wined3d_shader_descriptor_writes_vk_cleanup(&context_vk->descriptor_writes);
|
||||||
|
wine_rb_destroy(&context_vk->pipeline_layouts, wined3d_context_vk_destroy_pipeline_layout, context_vk);
|
||||||
wine_rb_destroy(&context_vk->render_passes, wined3d_context_vk_destroy_render_pass, context_vk);
|
wine_rb_destroy(&context_vk->render_passes, wined3d_context_vk_destroy_render_pass, context_vk);
|
||||||
|
|
||||||
wined3d_context_cleanup(&context_vk->c);
|
wined3d_context_cleanup(&context_vk->c);
|
||||||
|
@ -1175,6 +1196,17 @@ static int wined3d_render_pass_vk_compare(const void *key, const struct wine_rb_
|
||||||
return memcmp(k, &pass->key, sizeof(*k));
|
return memcmp(k, &pass->key, sizeof(*k));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wined3d_pipeline_layout_vk_compare(const void *key, const struct wine_rb_entry *entry)
|
||||||
|
{
|
||||||
|
const struct wined3d_pipeline_layout_key_vk *a = key;
|
||||||
|
const struct wined3d_pipeline_layout_key_vk *b = &WINE_RB_ENTRY_VALUE(entry,
|
||||||
|
const struct wined3d_pipeline_layout_vk, entry)->key;
|
||||||
|
|
||||||
|
if (a->binding_count != b->binding_count)
|
||||||
|
return a->binding_count - b->binding_count;
|
||||||
|
return memcmp(a->bindings, b->bindings, a->binding_count * sizeof(*a->bindings));
|
||||||
|
}
|
||||||
|
|
||||||
static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entry *entry)
|
static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entry *entry)
|
||||||
{
|
{
|
||||||
const struct wined3d_bo_slab_vk *slab = WINE_RB_ENTRY_VALUE(entry, const struct wined3d_bo_slab_vk, entry);
|
const struct wined3d_bo_slab_vk *slab = WINE_RB_ENTRY_VALUE(entry, const struct wined3d_bo_slab_vk, entry);
|
||||||
|
@ -1260,36 +1292,211 @@ static VkResult wined3d_context_vk_create_descriptor_set(struct wined3d_context_
|
||||||
return vr;
|
return vr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *context_vk,
|
static bool wined3d_shader_descriptor_writes_vk_add_write(struct wined3d_shader_descriptor_writes_vk *writes,
|
||||||
VkCommandBuffer vk_command_buffer)
|
VkDescriptorSet vk_descriptor_set, size_t binding_idx, VkDescriptorType type,
|
||||||
|
const VkDescriptorBufferInfo *buffer_info, const VkDescriptorImageInfo *image_info,
|
||||||
|
const VkBufferView *buffer_view)
|
||||||
{
|
{
|
||||||
|
SIZE_T write_count = writes->count;
|
||||||
|
VkWriteDescriptorSet *write;
|
||||||
|
|
||||||
|
if (!wined3d_array_reserve((void **)&writes->writes, &writes->size,
|
||||||
|
write_count + 1, sizeof(*writes->writes)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
write = &writes->writes[write_count];
|
||||||
|
write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
write->pNext = NULL;
|
||||||
|
write->dstSet = vk_descriptor_set;
|
||||||
|
write->dstBinding = binding_idx;
|
||||||
|
write->dstArrayElement = 0;
|
||||||
|
write->descriptorCount = 1;
|
||||||
|
write->descriptorType = type;
|
||||||
|
write->pImageInfo = image_info;
|
||||||
|
write->pBufferInfo = buffer_info;
|
||||||
|
write->pTexelBufferView = buffer_view;
|
||||||
|
|
||||||
|
++writes->count;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *context_vk,
|
||||||
|
VkCommandBuffer vk_command_buffer, const struct wined3d_state *state)
|
||||||
|
{
|
||||||
|
struct wined3d_shader_descriptor_writes_vk *writes = &context_vk->descriptor_writes;
|
||||||
|
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
|
||||||
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
|
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
|
||||||
const struct wined3d_shader_resource_binding *binding;
|
const struct wined3d_shader_resource_binding *binding;
|
||||||
struct wined3d_shader_resource_bindings *bindings;
|
struct wined3d_shader_resource_bindings *bindings;
|
||||||
|
const VkDescriptorBufferInfo *buffer_info;
|
||||||
VkDescriptorSet vk_descriptor_set;
|
VkDescriptorSet vk_descriptor_set;
|
||||||
|
struct wined3d_buffer *buffer;
|
||||||
VkResult vr;
|
VkResult vr;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
bindings = &context_vk->compute.bindings;
|
bindings = &context_vk->compute.bindings;
|
||||||
if ((vr = wined3d_context_vk_create_descriptor_set(context_vk,
|
if ((vr = wined3d_context_vk_create_descriptor_set(context_vk,
|
||||||
context_vk->vk_set_layout, &vk_descriptor_set)))
|
context_vk->compute.vk_set_layout, &vk_descriptor_set)))
|
||||||
{
|
{
|
||||||
WARN("Failed to create descriptor set, vr %s.\n", wined3d_debug_vkresult(vr));
|
WARN("Failed to create descriptor set, vr %s.\n", wined3d_debug_vkresult(vr));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bindings->count)
|
writes->count = 0;
|
||||||
|
for (i = 0; i < bindings->count; ++i)
|
||||||
{
|
{
|
||||||
binding = bindings->bindings;
|
binding = &bindings->bindings[i];
|
||||||
|
|
||||||
|
switch (binding->shader_descriptor_type)
|
||||||
|
{
|
||||||
|
case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV:
|
||||||
|
if (!(buffer = state->cb[binding->shader_type][binding->resource_idx]))
|
||||||
|
{
|
||||||
|
FIXME("NULL constant buffer views not implemented.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffer_info = wined3d_buffer_vk_get_buffer_info(wined3d_buffer_vk(buffer));
|
||||||
|
if (!wined3d_shader_descriptor_writes_vk_add_write(writes, vk_descriptor_set,
|
||||||
|
binding->binding_idx, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, buffer_info, NULL, NULL))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
FIXME("Unhandled descriptor type %#x.\n", binding->shader_descriptor_type);
|
FIXME("Unhandled descriptor type %#x.\n", binding->shader_descriptor_type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VK_CALL(vkUpdateDescriptorSets(device_vk->vk_device, writes->count, writes->writes, 0, NULL));
|
||||||
VK_CALL(vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE,
|
VK_CALL(vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||||
context_vk->vk_pipeline_layout, 0, 1, &vk_descriptor_set, 0, NULL));
|
context_vk->compute.vk_pipeline_layout, 0, 1, &vk_descriptor_set, 0, NULL));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkResult wined3d_context_vk_create_descriptor_set_layout(struct wined3d_device_vk *device_vk,
|
||||||
|
const struct wined3d_vk_info *vk_info, const struct wined3d_pipeline_layout_key_vk *key,
|
||||||
|
VkDescriptorSetLayout *vk_set_layout)
|
||||||
|
{
|
||||||
|
VkDescriptorSetLayoutCreateInfo layout_desc;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
layout_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
layout_desc.pNext = NULL;
|
||||||
|
layout_desc.flags = 0;
|
||||||
|
layout_desc.bindingCount = key->binding_count;
|
||||||
|
layout_desc.pBindings = key->bindings;
|
||||||
|
|
||||||
|
if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device_vk->vk_device, &layout_desc, NULL, vk_set_layout))) < 0)
|
||||||
|
WARN("Failed to create Vulkan descriptor set layout, vr %s.\n", wined3d_debug_vkresult(vr));
|
||||||
|
|
||||||
|
return vr;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wined3d_pipeline_layout_vk *wined3d_context_vk_get_pipeline_layout(
|
||||||
|
struct wined3d_context_vk *context_vk, VkDescriptorSetLayoutBinding *bindings, SIZE_T binding_count)
|
||||||
|
{
|
||||||
|
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_pipeline_layout_key_vk key;
|
||||||
|
struct wined3d_pipeline_layout_vk *layout;
|
||||||
|
VkPipelineLayoutCreateInfo layout_desc;
|
||||||
|
struct wine_rb_entry *entry;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
key.bindings = bindings;
|
||||||
|
key.binding_count = binding_count;
|
||||||
|
if ((entry = wine_rb_get(&context_vk->pipeline_layouts, &key)))
|
||||||
|
return WINE_RB_ENTRY_VALUE(entry, struct wined3d_pipeline_layout_vk, entry);
|
||||||
|
|
||||||
|
if (!(layout = heap_alloc(sizeof(*layout))))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(layout->key.bindings = heap_alloc(sizeof(*layout->key.bindings) * key.binding_count)))
|
||||||
|
{
|
||||||
|
heap_free(layout);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(layout->key.bindings, key.bindings, sizeof(*layout->key.bindings) * key.binding_count);
|
||||||
|
layout->key.binding_count = key.binding_count;
|
||||||
|
|
||||||
|
if ((vr = wined3d_context_vk_create_descriptor_set_layout(device_vk, vk_info, &key, &layout->vk_set_layout)))
|
||||||
|
{
|
||||||
|
WARN("Failed to create descriptor set layout, vr %s.\n", wined3d_debug_vkresult(vr));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
layout_desc.pNext = NULL;
|
||||||
|
layout_desc.flags = 0;
|
||||||
|
layout_desc.setLayoutCount = 1;
|
||||||
|
layout_desc.pSetLayouts = &layout->vk_set_layout;
|
||||||
|
layout_desc.pushConstantRangeCount = 0;
|
||||||
|
layout_desc.pPushConstantRanges = NULL;
|
||||||
|
|
||||||
|
if ((vr = VK_CALL(vkCreatePipelineLayout(device_vk->vk_device,
|
||||||
|
&layout_desc, NULL, &layout->vk_pipeline_layout))) < 0)
|
||||||
|
{
|
||||||
|
WARN("Failed to create Vulkan pipeline layout, vr %s.\n", wined3d_debug_vkresult(vr));
|
||||||
|
VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, layout->vk_set_layout, NULL));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wine_rb_put(&context_vk->pipeline_layouts, &layout->key, &layout->entry) == -1)
|
||||||
|
{
|
||||||
|
ERR("Failed to insert pipeline layout.\n");
|
||||||
|
VK_CALL(vkDestroyPipelineLayout(device_vk->vk_device, layout->vk_pipeline_layout, NULL));
|
||||||
|
VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, layout->vk_set_layout, NULL));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
heap_free(layout->key.bindings);
|
||||||
|
heap_free(layout);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk *context_vk,
|
||||||
|
const struct wined3d_state *state)
|
||||||
|
{
|
||||||
|
const struct wined3d_shader_resource_bindings *bindings = &context_vk->compute.bindings;
|
||||||
|
struct wined3d_shader_descriptor_writes_vk *writes = &context_vk->descriptor_writes;
|
||||||
|
const struct wined3d_shader_resource_binding *binding;
|
||||||
|
struct wined3d_buffer_vk *buffer_vk;
|
||||||
|
struct wined3d_buffer *buffer;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
writes->count = 0;
|
||||||
|
for (i = 0; i < bindings->count; ++i)
|
||||||
|
{
|
||||||
|
binding = &bindings->bindings[i];
|
||||||
|
|
||||||
|
switch (binding->shader_descriptor_type)
|
||||||
|
{
|
||||||
|
case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV:
|
||||||
|
if (!(buffer = state->cb[binding->shader_type][binding->resource_idx]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
buffer_vk = wined3d_buffer_vk(buffer);
|
||||||
|
wined3d_buffer_load(buffer, &context_vk->c, state);
|
||||||
|
if (!buffer_vk->bo_user.valid)
|
||||||
|
context_invalidate_compute_state(&context_vk->c, STATE_COMPUTE_CONSTANT_BUFFER);
|
||||||
|
wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FIXME("Unhandled descriptor type %#x.\n", binding->shader_descriptor_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk *context_vk,
|
VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk *context_vk,
|
||||||
const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk)
|
const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk)
|
||||||
{
|
{
|
||||||
|
@ -1314,6 +1521,8 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk
|
||||||
context_vk->update_compute_pipeline = 1;
|
context_vk->update_compute_pipeline = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wined3d_context_vk_load_shader_resources(context_vk, state);
|
||||||
|
|
||||||
if (indirect_vk)
|
if (indirect_vk)
|
||||||
wined3d_buffer_load_location(&indirect_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER);
|
wined3d_buffer_load_location(&indirect_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER);
|
||||||
|
|
||||||
|
@ -1339,7 +1548,7 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk
|
||||||
if (context_vk->c.update_compute_shader_resource_bindings
|
if (context_vk->c.update_compute_shader_resource_bindings
|
||||||
|| context_vk->c.update_compute_unordered_access_view_bindings)
|
|| context_vk->c.update_compute_unordered_access_view_bindings)
|
||||||
{
|
{
|
||||||
if (!wined3d_context_vk_update_descriptors(context_vk, vk_command_buffer))
|
if (!wined3d_context_vk_update_descriptors(context_vk, vk_command_buffer, state))
|
||||||
{
|
{
|
||||||
ERR("Failed to update shader descriptors.\n");
|
ERR("Failed to update shader descriptors.\n");
|
||||||
return VK_NULL_HANDLE;
|
return VK_NULL_HANDLE;
|
||||||
|
@ -1383,6 +1592,7 @@ HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wi
|
||||||
context_vk->current_command_buffer.id = 1;
|
context_vk->current_command_buffer.id = 1;
|
||||||
|
|
||||||
wine_rb_init(&context_vk->render_passes, wined3d_render_pass_vk_compare);
|
wine_rb_init(&context_vk->render_passes, wined3d_render_pass_vk_compare);
|
||||||
|
wine_rb_init(&context_vk->pipeline_layouts, wined3d_pipeline_layout_vk_compare);
|
||||||
wine_rb_init(&context_vk->bo_slab_available, wined3d_bo_slab_vk_compare);
|
wine_rb_init(&context_vk->bo_slab_available, wined3d_bo_slab_vk_compare);
|
||||||
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
|
|
|
@ -44,6 +44,8 @@ struct shader_spirv_compute_program_vk
|
||||||
{
|
{
|
||||||
VkShaderModule vk_module;
|
VkShaderModule vk_module;
|
||||||
VkPipeline vk_pipeline;
|
VkPipeline vk_pipeline;
|
||||||
|
VkPipelineLayout vk_pipeline_layout;
|
||||||
|
VkDescriptorSetLayout vk_set_layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void shader_spirv_handle_instruction(const struct wined3d_shader_instruction *ins)
|
static void shader_spirv_handle_instruction(const struct wined3d_shader_instruction *ins)
|
||||||
|
@ -65,8 +67,7 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program
|
||||||
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
|
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
|
||||||
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
|
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
|
||||||
struct shader_spirv_compute_program_vk *program;
|
struct shader_spirv_compute_program_vk *program;
|
||||||
VkDescriptorSetLayoutCreateInfo set_layout_desc;
|
struct wined3d_pipeline_layout_vk *layout;
|
||||||
VkPipelineLayoutCreateInfo pipeline_layout_desc;
|
|
||||||
VkComputePipelineCreateInfo pipeline_info;
|
VkComputePipelineCreateInfo pipeline_info;
|
||||||
VkResult vr;
|
VkResult vr;
|
||||||
|
|
||||||
|
@ -82,40 +83,15 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context_vk->vk_pipeline_layout)
|
if (!(layout = wined3d_context_vk_get_pipeline_layout(context_vk,
|
||||||
|
bindings->vk_bindings, bindings->vk_binding_count)))
|
||||||
{
|
{
|
||||||
set_layout_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
||||||
set_layout_desc.pNext = NULL;
|
|
||||||
set_layout_desc.flags = 0;
|
|
||||||
set_layout_desc.bindingCount = 0;
|
|
||||||
set_layout_desc.pBindings = NULL;
|
|
||||||
if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device_vk->vk_device,
|
|
||||||
&set_layout_desc, NULL, &context_vk->vk_set_layout))) < 0)
|
|
||||||
{
|
|
||||||
WARN("Failed to create Vulkan descriptor set layout, vr %s.\n", wined3d_debug_vkresult(vr));
|
|
||||||
VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
|
VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
|
||||||
heap_free(program);
|
heap_free(program);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
program->vk_set_layout = layout->vk_set_layout;
|
||||||
pipeline_layout_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
program->vk_pipeline_layout = layout->vk_pipeline_layout;
|
||||||
pipeline_layout_desc.pNext = NULL;
|
|
||||||
pipeline_layout_desc.flags = 0;
|
|
||||||
pipeline_layout_desc.setLayoutCount = 1;
|
|
||||||
pipeline_layout_desc.pSetLayouts = &context_vk->vk_set_layout;
|
|
||||||
pipeline_layout_desc.pushConstantRangeCount = 0;
|
|
||||||
pipeline_layout_desc.pPushConstantRanges = NULL;
|
|
||||||
|
|
||||||
if ((vr = VK_CALL(vkCreatePipelineLayout(device_vk->vk_device,
|
|
||||||
&pipeline_layout_desc, NULL, &context_vk->vk_pipeline_layout))) < 0)
|
|
||||||
{
|
|
||||||
WARN("Failed to create Vulkan pipeline layout, vr %s.\n", wined3d_debug_vkresult(vr));
|
|
||||||
VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, context_vk->vk_set_layout, NULL));
|
|
||||||
VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
|
|
||||||
heap_free(program);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||||
pipeline_info.pNext = NULL;
|
pipeline_info.pNext = NULL;
|
||||||
|
@ -127,7 +103,7 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program
|
||||||
pipeline_info.stage.pName = "main";
|
pipeline_info.stage.pName = "main";
|
||||||
pipeline_info.stage.pSpecializationInfo = NULL;
|
pipeline_info.stage.pSpecializationInfo = NULL;
|
||||||
pipeline_info.stage.module = program->vk_module;
|
pipeline_info.stage.module = program->vk_module;
|
||||||
pipeline_info.layout = context_vk->vk_pipeline_layout;
|
pipeline_info.layout = program->vk_pipeline_layout;
|
||||||
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
|
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
pipeline_info.basePipelineIndex = -1;
|
pipeline_info.basePipelineIndex = -1;
|
||||||
if ((vr = VK_CALL(vkCreateComputePipelines(device_vk->vk_device,
|
if ((vr = VK_CALL(vkCreateComputePipelines(device_vk->vk_device,
|
||||||
|
@ -342,9 +318,17 @@ static void shader_spirv_select_compute(void *shader_priv,
|
||||||
program = NULL;
|
program = NULL;
|
||||||
|
|
||||||
if (program)
|
if (program)
|
||||||
|
{
|
||||||
context_vk->compute.vk_pipeline = program->vk_pipeline;
|
context_vk->compute.vk_pipeline = program->vk_pipeline;
|
||||||
|
context_vk->compute.vk_set_layout = program->vk_set_layout;
|
||||||
|
context_vk->compute.vk_pipeline_layout = program->vk_pipeline_layout;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
|
context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
|
||||||
|
context_vk->compute.vk_set_layout = VK_NULL_HANDLE;
|
||||||
|
context_vk->compute.vk_pipeline_layout = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shader_spirv_disable(void *shader_priv, struct wined3d_context *context)
|
static void shader_spirv_disable(void *shader_priv, struct wined3d_context *context)
|
||||||
|
|
|
@ -1540,6 +1540,12 @@ static inline GLuint wined3d_bo_gl_id(uintptr_t bo)
|
||||||
return bo ? ((struct wined3d_bo_gl *)bo)->id : 0;
|
return bo ? ((struct wined3d_bo_gl *)bo)->id : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wined3d_bo_user_vk
|
||||||
|
{
|
||||||
|
struct list entry;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
struct wined3d_bo_vk
|
struct wined3d_bo_vk
|
||||||
{
|
{
|
||||||
VkBuffer vk_buffer;
|
VkBuffer vk_buffer;
|
||||||
|
@ -1554,6 +1560,7 @@ struct wined3d_bo_vk
|
||||||
VkBufferUsageFlags usage;
|
VkBufferUsageFlags usage;
|
||||||
VkMemoryPropertyFlags memory_type;
|
VkMemoryPropertyFlags memory_type;
|
||||||
|
|
||||||
|
struct list users;
|
||||||
uint64_t command_buffer_id;
|
uint64_t command_buffer_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2299,6 +2306,20 @@ struct wined3d_render_pass_vk
|
||||||
VkRenderPass vk_render_pass;
|
VkRenderPass vk_render_pass;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wined3d_pipeline_layout_key_vk
|
||||||
|
{
|
||||||
|
VkDescriptorSetLayoutBinding *bindings;
|
||||||
|
SIZE_T binding_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wined3d_pipeline_layout_vk
|
||||||
|
{
|
||||||
|
struct wine_rb_entry entry;
|
||||||
|
struct wined3d_pipeline_layout_key_vk key;
|
||||||
|
VkPipelineLayout vk_pipeline_layout;
|
||||||
|
VkDescriptorSetLayout vk_set_layout;
|
||||||
|
};
|
||||||
|
|
||||||
enum wined3d_shader_descriptor_type
|
enum wined3d_shader_descriptor_type
|
||||||
{
|
{
|
||||||
WINED3D_SHADER_DESCRIPTOR_TYPE_CBV,
|
WINED3D_SHADER_DESCRIPTOR_TYPE_CBV,
|
||||||
|
@ -2324,6 +2345,12 @@ struct wined3d_shader_resource_bindings
|
||||||
SIZE_T size, count;
|
SIZE_T size, count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wined3d_shader_descriptor_writes_vk
|
||||||
|
{
|
||||||
|
VkWriteDescriptorSet *writes;
|
||||||
|
SIZE_T size, count;
|
||||||
|
};
|
||||||
|
|
||||||
struct wined3d_context_vk
|
struct wined3d_context_vk
|
||||||
{
|
{
|
||||||
struct wined3d_context c;
|
struct wined3d_context c;
|
||||||
|
@ -2336,6 +2363,8 @@ struct wined3d_context_vk
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
VkPipeline vk_pipeline;
|
VkPipeline vk_pipeline;
|
||||||
|
VkPipelineLayout vk_pipeline_layout;
|
||||||
|
VkDescriptorSetLayout vk_set_layout;
|
||||||
struct wined3d_shader_resource_bindings bindings;
|
struct wined3d_shader_resource_bindings bindings;
|
||||||
} compute;
|
} compute;
|
||||||
|
|
||||||
|
@ -2350,12 +2379,13 @@ struct wined3d_context_vk
|
||||||
SIZE_T buffer_count;
|
SIZE_T buffer_count;
|
||||||
} submitted;
|
} submitted;
|
||||||
|
|
||||||
|
struct wined3d_shader_descriptor_writes_vk descriptor_writes;
|
||||||
|
|
||||||
VkDescriptorPool vk_descriptor_pool;
|
VkDescriptorPool vk_descriptor_pool;
|
||||||
VkPipelineLayout vk_pipeline_layout;
|
|
||||||
VkDescriptorSetLayout vk_set_layout;
|
|
||||||
|
|
||||||
struct wined3d_retired_objects_vk retired;
|
struct wined3d_retired_objects_vk retired;
|
||||||
struct wine_rb_tree render_passes;
|
struct wine_rb_tree render_passes;
|
||||||
|
struct wine_rb_tree pipeline_layouts;
|
||||||
struct wine_rb_tree bo_slab_available;
|
struct wine_rb_tree bo_slab_available;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2390,6 +2420,8 @@ void wined3d_context_vk_destroy_memory(struct wined3d_context_vk *context_vk,
|
||||||
void wined3d_context_vk_destroy_sampler(struct wined3d_context_vk *context_vk,
|
void wined3d_context_vk_destroy_sampler(struct wined3d_context_vk *context_vk,
|
||||||
VkSampler vk_sampler, uint64_t command_buffer_id) DECLSPEC_HIDDEN;
|
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;
|
VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
|
||||||
|
struct wined3d_pipeline_layout_vk *wined3d_context_vk_get_pipeline_layout(struct wined3d_context_vk *context_vk,
|
||||||
|
VkDescriptorSetLayoutBinding *bindings, SIZE_T binding_count) DECLSPEC_HIDDEN;
|
||||||
VkRenderPass wined3d_context_vk_get_render_pass(struct wined3d_context_vk *context_vk,
|
VkRenderPass wined3d_context_vk_get_render_pass(struct wined3d_context_vk *context_vk,
|
||||||
const struct wined3d_fb_state *fb, unsigned int rt_count,
|
const struct wined3d_fb_state *fb, unsigned int rt_count,
|
||||||
bool depth_stencil, uint32_t clear_flags) DECLSPEC_HIDDEN;
|
bool depth_stencil, uint32_t clear_flags) DECLSPEC_HIDDEN;
|
||||||
|
@ -4547,6 +4579,8 @@ struct wined3d_buffer_vk
|
||||||
struct wined3d_buffer b;
|
struct wined3d_buffer b;
|
||||||
|
|
||||||
struct wined3d_bo_vk bo;
|
struct wined3d_bo_vk bo;
|
||||||
|
struct wined3d_bo_user_vk bo_user;
|
||||||
|
VkDescriptorBufferInfo buffer_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct wined3d_buffer_vk *wined3d_buffer_vk(struct wined3d_buffer *buffer)
|
static inline struct wined3d_buffer_vk *wined3d_buffer_vk(struct wined3d_buffer *buffer)
|
||||||
|
@ -4554,6 +4588,7 @@ static inline struct wined3d_buffer_vk *wined3d_buffer_vk(struct wined3d_buffer
|
||||||
return CONTAINING_RECORD(buffer, struct wined3d_buffer_vk, b);
|
return CONTAINING_RECORD(buffer, struct wined3d_buffer_vk, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk) DECLSPEC_HIDDEN;
|
||||||
HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined3d_device *device,
|
HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined3d_device *device,
|
||||||
const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
|
const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
|
||||||
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
|
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue