wined3d: Create Vulkan buffers.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2020-01-24 19:32:03 +03:30 committed by Alexandre Julliard
parent 97ee54e9d6
commit dd03e37f9f
4 changed files with 173 additions and 3 deletions

View File

@ -555,6 +555,23 @@ static void adapter_vk_destroy_swapchain(struct wined3d_swapchain *swapchain)
heap_free(swapchain); heap_free(swapchain);
} }
unsigned int wined3d_adapter_vk_get_memory_type_index(const struct wined3d_adapter_vk *adapter_vk,
uint32_t memory_type_mask, VkMemoryPropertyFlags flags)
{
const VkPhysicalDeviceMemoryProperties *memory_info = &adapter_vk->memory_properties;
unsigned int i;
for (i = 0; i < memory_info->memoryTypeCount; ++i)
{
if (!(memory_type_mask & (1u << i)))
continue;
if ((memory_info->memoryTypes[i].propertyFlags & flags) == flags)
return i;
}
return ~0u;
}
static HRESULT adapter_vk_create_buffer(struct wined3d_device *device, static HRESULT adapter_vk_create_buffer(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, struct wined3d_buffer **buffer) void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)

View File

@ -1554,6 +1554,44 @@ HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined
return wined3d_buffer_init(&buffer_gl->b, device, desc, data, parent, parent_ops, &wined3d_buffer_gl_ops); return wined3d_buffer_init(&buffer_gl->b, device, desc, data, parent, parent_ops, &wined3d_buffer_gl_ops);
} }
static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buffer_vk,
struct wined3d_context_vk *context_vk)
{
struct wined3d_resource *resource = &buffer_vk->b.resource;
uint32_t bind_flags = resource->bind_flags;
VkMemoryPropertyFlags memory_type;
VkBufferUsageFlags usage;
usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
if (bind_flags & WINED3D_BIND_VERTEX_BUFFER)
usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
if (bind_flags & WINED3D_BIND_INDEX_BUFFER)
usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
if (bind_flags & WINED3D_BIND_CONSTANT_BUFFER)
usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
if (bind_flags & WINED3D_BIND_SHADER_RESOURCE)
usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
if (bind_flags & WINED3D_BIND_UNORDERED_ACCESS)
usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
if (bind_flags & WINED3D_BIND_INDIRECT_BUFFER)
usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
if (bind_flags & (WINED3D_BIND_STREAM_OUTPUT | WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL))
FIXME("Ignoring some bind flags %#x.\n", bind_flags);
memory_type = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
if (!(wined3d_context_vk_create_bo(context_vk, resource->size, usage, memory_type, &buffer_vk->bo)))
{
WARN("Failed to create Vulkan buffer.\n");
return FALSE;
}
buffer_vk->b.buffer_object = (uintptr_t)&buffer_vk->bo;
buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
return TRUE;
}
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)
{ {
@ -1563,9 +1601,11 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
return wined3d_resource_prepare_sysmem(&buffer->resource); return wined3d_resource_prepare_sysmem(&buffer->resource);
case WINED3D_LOCATION_BUFFER: case WINED3D_LOCATION_BUFFER:
/* The Vulkan buffer is created during resource creation. */ if (buffer->buffer_object)
return TRUE; return TRUE;
return wined3d_buffer_vk_create_buffer_object(wined3d_buffer_vk(buffer), wined3d_context_vk(context));
default: default:
FIXME("Unhandled location %s.\n", wined3d_debug_location(location)); FIXME("Unhandled location %s.\n", wined3d_debug_location(location));
return FALSE; return FALSE;
@ -1575,7 +1615,24 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer, static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, unsigned int location) struct wined3d_context *context, unsigned int location)
{ {
FIXME("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location)); struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
struct wined3d_buffer_vk *buffer_vk = wined3d_buffer_vk(buffer);
TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
switch (location)
{
case WINED3D_LOCATION_BUFFER:
wined3d_context_vk_destroy_bo(context_vk, &buffer_vk->bo);
buffer_vk->bo.vk_buffer = VK_NULL_HANDLE;
buffer_vk->bo.vk_memory = VK_NULL_HANDLE;
buffer_vk->b.buffer_object = 0u;
break;
default:
ERR("Unhandled location %s.\n", wined3d_debug_location(location));
break;
}
} }
static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context, static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
@ -1605,6 +1662,9 @@ HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined
TRACE("buffer_vk %p, device %p, desc %p, data %p, parent %p, parent_ops %p.\n", TRACE("buffer_vk %p, device %p, desc %p, data %p, parent %p, parent_ops %p.\n",
buffer_vk, device, desc, data, parent, parent_ops); buffer_vk, device, desc, data, parent, parent_ops);
if (desc->access & WINED3D_RESOURCE_ACCESS_GPU)
buffer_vk->b.flags |= WINED3D_BUFFER_USE_BO;
return wined3d_buffer_init(&buffer_vk->b, device, desc, data, parent, parent_ops, &wined3d_buffer_vk_ops); return wined3d_buffer_init(&buffer_vk->b, device, desc, data, parent, parent_ops, &wined3d_buffer_vk_ops);
} }

View File

@ -1493,6 +1493,74 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
wined3d_context_cleanup(&context_gl->c); wined3d_context_cleanup(&context_gl->c);
} }
BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size,
VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
VkMemoryRequirements memory_requirements;
struct wined3d_adapter_vk *adapter_vk;
VkMemoryAllocateInfo allocate_info;
VkBufferCreateInfo create_info;
VkResult vr;
adapter_vk = wined3d_adapter_vk(device_vk->d.adapter);
create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
create_info.pNext = NULL;
create_info.flags = 0;
create_info.size = size;
create_info.usage = usage;
create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
create_info.queueFamilyIndexCount = 0;
create_info.pQueueFamilyIndices = NULL;
if ((vr = VK_CALL(vkCreateBuffer(device_vk->vk_device, &create_info, NULL, &bo->vk_buffer))) < 0)
{
ERR("Failed to create Vulkan buffer, vr %s.\n", wined3d_debug_vkresult(vr));
return FALSE;
}
VK_CALL(vkGetBufferMemoryRequirements(device_vk->vk_device, bo->vk_buffer, &memory_requirements));
allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocate_info.pNext = NULL;
allocate_info.allocationSize = memory_requirements.size;
allocate_info.memoryTypeIndex = wined3d_adapter_vk_get_memory_type_index(adapter_vk,
memory_requirements.memoryTypeBits, memory_type);
if (allocate_info.memoryTypeIndex == ~0u)
{
ERR("Failed to find suitable memory type.\n");
VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL));
return FALSE;
}
if ((vr = VK_CALL(vkAllocateMemory(device_vk->vk_device, &allocate_info, NULL, &bo->vk_memory))) < 0)
{
ERR("Failed to allocate buffer memory, vr %s.\n", wined3d_debug_vkresult(vr));
VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL));
return FALSE;
}
if ((vr = VK_CALL(vkBindBufferMemory(device_vk->vk_device, bo->vk_buffer, bo->vk_memory, 0))) < 0)
{
ERR("Failed to bind buffer memory, vr %s.\n", wined3d_debug_vkresult(vr));
VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL));
VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL));
return FALSE;
}
return TRUE;
}
void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const struct wined3d_bo_vk *bo)
{
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL));
VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL));
}
void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
{ {
wined3d_context_cleanup(&context_vk->c); wined3d_context_cleanup(&context_vk->c);
@ -2344,9 +2412,13 @@ fail:
HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wined3d_swapchain *swapchain) HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wined3d_swapchain *swapchain)
{ {
struct wined3d_adapter_vk *adapter_vk;
TRACE("context_vk %p, swapchain %p.\n", context_vk, swapchain); TRACE("context_vk %p, swapchain %p.\n", context_vk, swapchain);
wined3d_context_init(&context_vk->c, swapchain); wined3d_context_init(&context_vk->c, swapchain);
adapter_vk = wined3d_adapter_vk(swapchain->device->adapter);
context_vk->vk_info = &adapter_vk->vk_info;
return WINED3D_OK; return WINED3D_OK;
} }

View File

@ -1512,6 +1512,12 @@ do { \
#define checkGLcall(A) do {} while(0) #define checkGLcall(A) do {} while(0)
#endif #endif
struct wined3d_bo_vk
{
VkBuffer vk_buffer;
VkDeviceMemory vk_memory;
};
struct wined3d_bo_address struct wined3d_bo_address
{ {
UINT_PTR buffer_object; UINT_PTR buffer_object;
@ -2155,9 +2161,20 @@ void wined3d_context_gl_update_stream_sources(struct wined3d_context_gl *context
struct wined3d_context_vk struct wined3d_context_vk
{ {
struct wined3d_context c; struct wined3d_context c;
const struct wined3d_vk_info *vk_info;
}; };
static inline struct wined3d_context_vk *wined3d_context_vk(struct wined3d_context *context)
{
return CONTAINING_RECORD(context, struct wined3d_context_vk, c);
}
void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size,
VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN;
void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk,
const struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN;
HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
@ -2929,6 +2946,8 @@ static inline struct wined3d_adapter_vk *wined3d_adapter_vk(struct wined3d_adapt
struct wined3d_adapter *wined3d_adapter_vk_create(unsigned int ordinal, struct wined3d_adapter *wined3d_adapter_vk_create(unsigned int ordinal,
unsigned int wined3d_creation_flags) DECLSPEC_HIDDEN; unsigned int wined3d_creation_flags) DECLSPEC_HIDDEN;
unsigned int wined3d_adapter_vk_get_memory_type_index(const struct wined3d_adapter_vk *adapter_vk,
uint32_t memory_type_mask, VkMemoryPropertyFlags flags) DECLSPEC_HIDDEN;
struct wined3d_caps_gl_ctx struct wined3d_caps_gl_ctx
{ {
@ -4208,6 +4227,8 @@ HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined
struct wined3d_buffer_vk struct wined3d_buffer_vk
{ {
struct wined3d_buffer b; struct wined3d_buffer b;
struct wined3d_bo_vk bo;
}; };
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)