libs/vkd3d: Implement committed buffer resources.

This commit is contained in:
Józef Kucia 2016-09-27 12:13:37 +02:00
parent fec147c2cb
commit fc1492766e
2 changed files with 118 additions and 21 deletions

View File

@ -62,6 +62,50 @@ static VkSampleCountFlagBits vk_samples_from_dxgi_sample_desc(const DXGI_SAMPLE_
} }
} }
static HRESULT vkd3d_create_buffer(struct d3d12_resource *resource, struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
VkBufferCreateInfo buffer_info;
VkResult vr;
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_info.pNext = NULL;
buffer_info.flags = 0;
buffer_info.size = desc->Width;
/* FIXME: Try to limit usage based on heap_properties. */
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT
| VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
| VK_BUFFER_USAGE_INDEX_BUFFER_BIT
| VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
| VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
{
buffer_info.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
buffer_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
}
if (!(desc->Flags & D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE))
buffer_info.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
/* FIXME: Buffers always can be accessed from multiple queues. */
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
buffer_info.queueFamilyIndexCount = 0;
buffer_info.pQueueFamilyIndices = 0;
if ((vr = VK_CALL(vkCreateBuffer(device->vk_device, &buffer_info, NULL, &resource->u.vk_buffer))))
{
WARN("Failed to create Vulkan buffer, vr %d.\n", vr);
return hresult_from_vk_result(vr);
}
TRACE("Created Vulkan buffer for resource %p.\n", resource);
return S_OK;
}
static HRESULT vkd3d_create_image(struct d3d12_resource *resource, struct d3d12_device *device, static HRESULT vkd3d_create_image(struct d3d12_resource *resource, struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state) const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state)
@ -135,7 +179,7 @@ static HRESULT vkd3d_create_image(struct d3d12_resource *resource, struct d3d12_
FIXME("Ignoring initial state %#x.\n", initial_state); FIXME("Ignoring initial state %#x.\n", initial_state);
if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, &resource->vk_image)))) if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, &resource->u.vk_image))))
{ {
WARN("Failed to create Vulkan image, vr %d.\n", vr); WARN("Failed to create Vulkan image, vr %d.\n", vr);
return hresult_from_vk_result(vr); return hresult_from_vk_result(vr);
@ -180,43 +224,86 @@ static unsigned int vkd3d_select_memory_type(struct d3d12_device *device, uint32
return ~0u; return ~0u;
} }
static HRESULT vkd3d_allocate_image_memory(struct d3d12_resource *resource, struct d3d12_device *device, static HRESULT vkd3d_allocate_device_memory(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags) const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const VkMemoryRequirements *memory_requirements, VkDeviceMemory *vk_memory)
{ {
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
VkMemoryRequirements memory_requirements;
VkMemoryAllocateInfo allocate_info; VkMemoryAllocateInfo allocate_info;
VkResult vr; VkResult vr;
assert(D3D12_RESOURCE_DIMENSION_TEXTURE1D <= resource->desc.Dimension
&& resource->desc.Dimension <= D3D12_RESOURCE_DIMENSION_TEXTURE3D);
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, resource->vk_image, &memory_requirements));
TRACE("Memory requirements: size %s, alignment %s.\n", TRACE("Memory requirements: size %s, alignment %s.\n",
debugstr_uint64(memory_requirements.size), debugstr_uint64(memory_requirements.alignment)); debugstr_uint64(memory_requirements->size),
debugstr_uint64(memory_requirements->alignment));
allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocate_info.pNext = NULL; allocate_info.pNext = NULL;
allocate_info.allocationSize = memory_requirements.size; allocate_info.allocationSize = memory_requirements->size;
allocate_info.memoryTypeIndex = vkd3d_select_memory_type(device, allocate_info.memoryTypeIndex = vkd3d_select_memory_type(device,
memory_requirements.memoryTypeBits, heap_properties, heap_flags); memory_requirements->memoryTypeBits, heap_properties, heap_flags);
if (allocate_info.memoryTypeIndex == ~0u) if (allocate_info.memoryTypeIndex == ~0u)
{ {
ERR("Failed to find memory type.\n"); ERR("Failed to find suitable memory type.\n");
*vk_memory = VK_NULL_HANDLE;
return E_FAIL; return E_FAIL;
} }
TRACE("Allocating memory type %u.\n", allocate_info.memoryTypeIndex); TRACE("Allocating memory type %u.\n", allocate_info.memoryTypeIndex);
if ((vr = VK_CALL(vkAllocateMemory(device->vk_device, &allocate_info, NULL, &resource->vk_memory)))) if ((vr = VK_CALL(vkAllocateMemory(device->vk_device, &allocate_info, NULL, vk_memory))))
{ {
WARN("Failed to allocate memory, vr %d.\n", vr); WARN("Failed to allocate device memory, vr %d.\n", vr);
*vk_memory = VK_NULL_HANDLE;
return hresult_from_vk_result(vr); return hresult_from_vk_result(vr);
} }
if ((vr = VK_CALL(vkBindImageMemory(device->vk_device, resource->vk_image, resource->vk_memory, 0)))) return S_OK;
}
static HRESULT vkd3d_allocate_buffer_memory(struct d3d12_resource *resource, struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
VkMemoryRequirements memory_requirements;
VkResult vr;
HRESULT hr;
assert(resource->desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER);
VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &memory_requirements));
if (FAILED(hr = vkd3d_allocate_device_memory(device, heap_properties, heap_flags,
&memory_requirements, &resource->vk_memory)))
return hr;
if ((vr = VK_CALL(vkBindBufferMemory(device->vk_device, resource->u.vk_buffer, resource->vk_memory, 0))))
{
WARN("Failed to bind memory, vr %d.\n", vr);
VK_CALL(vkFreeMemory(device->vk_device, resource->vk_memory, NULL));
resource->vk_memory = VK_NULL_HANDLE;
return hresult_from_vk_result(vr);
}
return S_OK;
}
static HRESULT vkd3d_allocate_image_memory(struct d3d12_resource *resource, struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
VkMemoryRequirements memory_requirements;
VkResult vr;
HRESULT hr;
assert(D3D12_RESOURCE_DIMENSION_TEXTURE1D <= resource->desc.Dimension
&& resource->desc.Dimension <= D3D12_RESOURCE_DIMENSION_TEXTURE3D);
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, resource->u.vk_image, &memory_requirements));
if (FAILED(hr = vkd3d_allocate_device_memory(device, heap_properties, heap_flags,
&memory_requirements, &resource->vk_memory)))
return hr;
if ((vr = VK_CALL(vkBindImageMemory(device->vk_device, resource->u.vk_image, resource->vk_memory, 0))))
{ {
WARN("Failed to bind memory, vr %d.\n", vr); WARN("Failed to bind memory, vr %d.\n", vr);
VK_CALL(vkFreeMemory(device->vk_device, resource->vk_memory, NULL)); VK_CALL(vkFreeMemory(device->vk_device, resource->vk_memory, NULL));
@ -234,13 +321,13 @@ static void vkd3d_destroy_resource(struct d3d12_resource *resource, struct d3d12
switch (resource->desc.Dimension) switch (resource->desc.Dimension)
{ {
case D3D12_RESOURCE_DIMENSION_BUFFER: case D3D12_RESOURCE_DIMENSION_BUFFER:
FIXME("Unhandled buffer resource.\n"); VK_CALL(vkDestroyBuffer(device->vk_device, resource->u.vk_buffer, NULL));
break; break;
case D3D12_RESOURCE_DIMENSION_TEXTURE1D: case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
case D3D12_RESOURCE_DIMENSION_TEXTURE2D: case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
case D3D12_RESOURCE_DIMENSION_TEXTURE3D: case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
VK_CALL(vkDestroyImage(device->vk_device, resource->vk_image, NULL)); VK_CALL(vkDestroyImage(device->vk_device, resource->u.vk_image, NULL));
break; break;
default: default:
@ -459,8 +546,14 @@ static HRESULT d3d12_committed_resource_init(struct d3d12_resource *resource, st
switch (desc->Dimension) switch (desc->Dimension)
{ {
case D3D12_RESOURCE_DIMENSION_BUFFER: case D3D12_RESOURCE_DIMENSION_BUFFER:
FIXME("Unhandled buffer resource.\n"); if (FAILED(hr = vkd3d_create_buffer(resource, device, heap_properties, heap_flags,
resource->vk_memory = VK_NULL_HANDLE; desc, initial_state)))
return hr;
if (FAILED(hr = vkd3d_allocate_buffer_memory(resource, device, heap_properties, heap_flags)))
{
vkd3d_destroy_resource(resource, device);
return hr;
}
break; break;
case D3D12_RESOURCE_DIMENSION_TEXTURE1D: case D3D12_RESOURCE_DIMENSION_TEXTURE1D:

View File

@ -50,7 +50,11 @@ struct d3d12_resource
D3D12_RESOURCE_DESC desc; D3D12_RESOURCE_DESC desc;
VkImage vk_image; union
{
VkBuffer vk_buffer;
VkImage vk_image;
} u;
VkDeviceMemory vk_memory; VkDeviceMemory vk_memory;
struct d3d12_device *device; struct d3d12_device *device;