mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
libs/vkd3d: Implement committed buffer resources.
This commit is contained in:
parent
fec147c2cb
commit
fc1492766e
@ -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:
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user