From b0e47baebf6039ac3d264ce53fe512d8f7fb290e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Wed, 9 Aug 2017 18:44:16 +0200 Subject: [PATCH] libs/vkd3d: Implement d3d12_command_list_Set{Compute,Graphics}RootUnorderedAccessView(). --- libs/vkd3d/command.c | 190 +++++++++++++++++++++++++------------ libs/vkd3d/resource.c | 14 ++- libs/vkd3d/state.c | 2 +- libs/vkd3d/vkd3d_private.h | 8 +- 4 files changed, 148 insertions(+), 66 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 3f627add..f6cd0213 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -662,6 +662,18 @@ static bool d3d12_command_allocator_add_descriptor_pool(struct d3d12_command_all return true; } +static bool d3d12_command_allocator_add_buffer_view(struct d3d12_command_allocator *allocator, + VkBufferView view) +{ + if (!vkd3d_array_reserve((void **)&allocator->buffer_views, &allocator->buffer_views_size, + allocator->buffer_view_count + 1, sizeof(*allocator->buffer_views))) + return false; + + allocator->buffer_views[allocator->buffer_view_count++] = view; + + return true; +} + static void d3d12_command_list_allocator_destroyed(struct d3d12_command_list *list) { TRACE("list %p.\n", list); @@ -670,6 +682,64 @@ static void d3d12_command_list_allocator_destroyed(struct d3d12_command_list *li list->vk_command_buffer = VK_NULL_HANDLE; } +static void d3d12_command_allocator_free_resources(struct d3d12_command_allocator *allocator, + bool should_destroy) +{ + struct d3d12_device *device = allocator->device; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + unsigned int i; + + for (i = 0; i < allocator->buffer_view_count; ++i) + { + VK_CALL(vkDestroyBufferView(device->vk_device, allocator->buffer_views[i], NULL)); + } + allocator->buffer_view_count = 0; + + for (i = 0; i < allocator->descriptor_pool_count; ++i) + { + VK_CALL(vkDestroyDescriptorPool(device->vk_device, allocator->descriptor_pools[i], NULL)); + } + allocator->descriptor_pool_count = 0; + + for (i = 0; i < allocator->pipeline_count; ++i) + { + VK_CALL(vkDestroyPipeline(device->vk_device, allocator->pipelines[i], NULL)); + } + allocator->pipeline_count = 0; + + for (i = 0; i < allocator->framebuffer_count; ++i) + { + VK_CALL(vkDestroyFramebuffer(device->vk_device, allocator->framebuffers[i], NULL)); + } + allocator->framebuffer_count = 0; + + for (i = 0; i < allocator->pass_count; ++i) + { + VK_CALL(vkDestroyRenderPass(device->vk_device, allocator->passes[i], NULL)); + } + allocator->pass_count = 0; + + if (should_destroy) + { + vkd3d_free(allocator->buffer_views); + vkd3d_free(allocator->descriptor_pools); + vkd3d_free(allocator->pipelines); + vkd3d_free(allocator->framebuffers); + vkd3d_free(allocator->passes); + + /* All command buffers are implicitly freed when a pool is destroyed. */ + vkd3d_free(allocator->command_buffers); + allocator->command_buffer_count = 0; + VK_CALL(vkDestroyCommandPool(device->vk_device, allocator->vk_command_pool, NULL)); + } + else if (allocator->command_buffer_count) + { + VK_CALL(vkFreeCommandBuffers(device->vk_device, allocator->vk_command_pool, + allocator->command_buffer_count, allocator->command_buffers)); + allocator->command_buffer_count = 0; + } +} + /* ID3D12CommandAllocator */ static inline struct d3d12_command_allocator *impl_from_ID3D12CommandAllocator(ID3D12CommandAllocator *iface) { @@ -718,40 +788,11 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllo if (!refcount) { struct d3d12_device *device = allocator->device; - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - unsigned int i; if (allocator->current_command_list) d3d12_command_list_allocator_destroyed(allocator->current_command_list); - for (i = 0; i < allocator->descriptor_pool_count; ++i) - { - VK_CALL(vkDestroyDescriptorPool(device->vk_device, allocator->descriptor_pools[i], NULL)); - } - vkd3d_free(allocator->descriptor_pools); - - for (i = 0; i < allocator->pipeline_count; ++i) - { - VK_CALL(vkDestroyPipeline(device->vk_device, allocator->pipelines[i], NULL)); - } - vkd3d_free(allocator->pipelines); - - for (i = 0; i < allocator->framebuffer_count; ++i) - { - VK_CALL(vkDestroyFramebuffer(device->vk_device, allocator->framebuffers[i], NULL)); - } - vkd3d_free(allocator->framebuffers); - - for (i = 0; i < allocator->pass_count; ++i) - { - VK_CALL(vkDestroyRenderPass(device->vk_device, allocator->passes[i], NULL)); - } - vkd3d_free(allocator->passes); - - /* All command buffers are implicitly freed when a pool is destroyed. */ - vkd3d_free(allocator->command_buffers); - VK_CALL(vkDestroyCommandPool(device->vk_device, allocator->vk_command_pool, NULL)); - + d3d12_command_allocator_free_resources(allocator, true); vkd3d_free(allocator); ID3D12Device_Release(&device->ID3D12Device_iface); @@ -807,7 +848,6 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_allocator_Reset(ID3D12CommandAllo const struct vkd3d_vk_device_procs *vk_procs; struct d3d12_command_list *list; struct d3d12_device *device; - unsigned int i; VkResult vr; TRACE("iface %p.\n", iface); @@ -826,36 +866,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_allocator_Reset(ID3D12CommandAllo device = allocator->device; vk_procs = &device->vk_procs; - for (i = 0; i < allocator->descriptor_pool_count; ++i) - { - VK_CALL(vkDestroyDescriptorPool(device->vk_device, allocator->descriptor_pools[i], NULL)); - } - allocator->descriptor_pool_count = 0; - - for (i = 0; i < allocator->pipeline_count; ++i) - { - VK_CALL(vkDestroyPipeline(device->vk_device, allocator->pipelines[i], NULL)); - } - allocator->pipeline_count = 0; - - for (i = 0; i < allocator->framebuffer_count; ++i) - { - VK_CALL(vkDestroyFramebuffer(device->vk_device, allocator->framebuffers[i], NULL)); - } - allocator->framebuffer_count = 0; - - for (i = 0; i < allocator->pass_count; ++i) - { - VK_CALL(vkDestroyRenderPass(device->vk_device, allocator->passes[i], NULL)); - } - allocator->pass_count = 0; - - if (allocator->command_buffer_count) - { - VK_CALL(vkFreeCommandBuffers(device->vk_device, allocator->vk_command_pool, - allocator->command_buffer_count, allocator->command_buffers)); - allocator->command_buffer_count = 0; - } + d3d12_command_allocator_free_resources(allocator, false); if ((vr = VK_CALL(vkResetCommandPool(device->vk_device, allocator->vk_command_pool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT)))) @@ -947,6 +958,10 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo allocator->descriptor_pools_size = 0; allocator->descriptor_pool_count = 0; + allocator->buffer_views = NULL; + allocator->buffer_views_size = 0; + allocator->buffer_view_count = 0; + allocator->command_buffers = NULL; allocator->command_buffers_size = 0; allocator->command_buffer_count = 0; @@ -2535,6 +2550,45 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferVi list->graphics_descriptor_set, root_parameter_index, address); } +static void d3d12_command_list_set_root_uav(struct d3d12_command_list *list, + struct d3d12_root_signature *root_signature, VkDescriptorSet descriptor_set, + unsigned int index, D3D12_GPU_VIRTUAL_ADDRESS gpu_address) +{ + const struct d3d12_root_descriptor *root_descriptor = &root_signature->parameters[index].u.descriptor; + const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + struct VkWriteDescriptorSet descriptor_write; + VkDevice vk_device = list->device->vk_device; + VkBufferView vk_buffer_view; + + assert(root_signature->parameters[index].parameter_type == D3D12_ROOT_PARAMETER_TYPE_UAV); + + /* FIXME: Re-use buffer views. */ + if (!vkd3d_create_raw_buffer_uav(list->device, gpu_address, &vk_buffer_view)) + { + ERR("Failed to create buffer view.\n"); + return; + } + + if (!(d3d12_command_allocator_add_buffer_view(list->allocator, vk_buffer_view))) + { + ERR("Failed to add buffer view.\n"); + VK_CALL(vkDestroyBufferView(vk_device, vk_buffer_view, NULL)); + return; + } + + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.pNext = NULL; + descriptor_write.dstSet = descriptor_set; + descriptor_write.dstBinding = root_descriptor->binding; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorCount = 1; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + descriptor_write.pImageInfo = NULL; + descriptor_write.pBufferInfo = NULL; + descriptor_write.pTexelBufferView = &vk_buffer_view; + VK_CALL(vkUpdateDescriptorSets(vk_device, 1, &descriptor_write, 0, NULL)); +} + static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView( ID3D12GraphicsCommandList *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { @@ -2552,15 +2606,25 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessView( ID3D12GraphicsCommandList *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - FIXME("iface %p, root_parameter_index %u, address %#"PRIx64" stub!\n", + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); + + d3d12_command_list_set_root_uav(list, list->compute_root_signature, + list->compute_descriptor_set, root_parameter_index, address); } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessView( ID3D12GraphicsCommandList *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - FIXME("iface %p, root_parameter_index %u, address %#"PRIx64" stub!\n", + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); + + d3d12_command_list_set_root_uav(list, list->graphics_root_signature, + list->graphics_descriptor_set, root_parameter_index, address); } static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList *iface, diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 1064c24c..47a38afa 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1000,6 +1000,18 @@ void d3d12_desc_create_uav(struct d3d12_desc *descriptor, vkd3d_create_texture_uav(descriptor, device, resource, desc); } +bool vkd3d_create_raw_buffer_uav(struct d3d12_device *device, + D3D12_GPU_VIRTUAL_ADDRESS gpu_address, VkBufferView *vk_buffer_view) +{ + const struct vkd3d_format *format; + struct d3d12_resource *resource; + + format = vkd3d_get_format(DXGI_FORMAT_R32_UINT); + resource = vkd3d_gpu_va_allocator_dereference(&device->gpu_va_allocator, gpu_address); + return !vkd3d_create_buffer_view(device, resource, format, + gpu_address - resource->gpu_address, VK_WHOLE_SIZE, vk_buffer_view); +} + /* samplers */ static VkFilter vk_filter_from_d3d12(D3D12_FILTER_TYPE type) { @@ -1114,7 +1126,7 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler, sampler->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLER; } -HRESULT d3d12_device_create_static_sampler(struct d3d12_device *device, +HRESULT vkd3d_create_static_sampler(struct d3d12_device *device, const D3D12_STATIC_SAMPLER_DESC *desc, VkSampler *vk_sampler) { VkResult vr; diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 9f7e219e..75a8446b 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -734,7 +734,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa if (s->RegisterSpace) FIXME("Unhandled register space %u for static sampler %u.\n", s->RegisterSpace, i); - if (FAILED(hr = d3d12_device_create_static_sampler(device, s, &root_signature->static_samplers[i]))) + if (FAILED(hr = vkd3d_create_static_sampler(device, s, &root_signature->static_samplers[i]))) goto fail; cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature, diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index f9be6a06..7604acf8 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -203,7 +203,9 @@ void d3d12_desc_create_uav(struct d3d12_desc *descriptor, void d3d12_desc_create_sampler(struct d3d12_desc *sampler, struct d3d12_device *device, const D3D12_SAMPLER_DESC *desc) DECLSPEC_HIDDEN; -HRESULT d3d12_device_create_static_sampler(struct d3d12_device *device, +bool vkd3d_create_raw_buffer_uav(struct d3d12_device *device, + D3D12_GPU_VIRTUAL_ADDRESS gpu_address, VkBufferView *vk_buffer_view) DECLSPEC_HIDDEN; +HRESULT vkd3d_create_static_sampler(struct d3d12_device *device, const D3D12_STATIC_SAMPLER_DESC *desc, VkSampler *vk_sampler) DECLSPEC_HIDDEN; struct d3d12_rtv_desc @@ -400,6 +402,10 @@ struct d3d12_command_allocator size_t descriptor_pools_size; size_t descriptor_pool_count; + VkBufferView *buffer_views; + size_t buffer_views_size; + size_t buffer_view_count; + VkCommandBuffer *command_buffers; size_t command_buffers_size; size_t command_buffer_count;