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:
parent
97ee54e9d6
commit
dd03e37f9f
|
@ -555,6 +555,23 @@ static void adapter_vk_destroy_swapchain(struct wined3d_swapchain *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,
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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,
|
||||
struct wined3d_context *context, unsigned int location)
|
||||
{
|
||||
|
@ -1563,8 +1601,10 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
|
|||
return wined3d_resource_prepare_sysmem(&buffer->resource);
|
||||
|
||||
case WINED3D_LOCATION_BUFFER:
|
||||
/* The Vulkan buffer is created during resource creation. */
|
||||
return TRUE;
|
||||
if (buffer->buffer_object)
|
||||
return TRUE;
|
||||
|
||||
return wined3d_buffer_vk_create_buffer_object(wined3d_buffer_vk(buffer), wined3d_context_vk(context));
|
||||
|
||||
default:
|
||||
FIXME("Unhandled location %s.\n", wined3d_debug_location(location));
|
||||
|
@ -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,
|
||||
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,
|
||||
|
@ -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",
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1493,6 +1493,74 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
struct wined3d_adapter_vk *adapter_vk;
|
||||
|
||||
TRACE("context_vk %p, swapchain %p.\n", context_vk, 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;
|
||||
}
|
||||
|
|
|
@ -1512,6 +1512,12 @@ do { \
|
|||
#define checkGLcall(A) do {} while(0)
|
||||
#endif
|
||||
|
||||
struct wined3d_bo_vk
|
||||
{
|
||||
VkBuffer vk_buffer;
|
||||
VkDeviceMemory vk_memory;
|
||||
};
|
||||
|
||||
struct wined3d_bo_address
|
||||
{
|
||||
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 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;
|
||||
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,
|
||||
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,
|
||||
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
|
||||
{
|
||||
|
@ -4208,6 +4227,8 @@ HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined
|
|||
struct wined3d_buffer_vk
|
||||
{
|
||||
struct wined3d_buffer b;
|
||||
|
||||
struct wined3d_bo_vk bo;
|
||||
};
|
||||
|
||||
static inline struct wined3d_buffer_vk *wined3d_buffer_vk(struct wined3d_buffer *buffer)
|
||||
|
|
Loading…
Reference in New Issue