[PATCH 1/5] wined3d: Create Vulkan buffers.
Henri Verbeet
hverbeet at codeweavers.com
Fri Dec 13 15:31:11 CST 2019
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 17 ++++++++++
dlls/wined3d/buffer.c | 66 ++++++++++++++++++++++++++++++++++++--
dlls/wined3d/context.c | 72 ++++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 21 ++++++++++++
4 files changed, 173 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 4ec68013017..7d501b4b08f 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -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)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 5da6aec4fb8..4f3c28fe0b1 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -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);
}
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 95769014af6..5d88d4463f9 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -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;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 21f17736ec7..583d970eca8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -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)
--
2.11.0
More information about the wine-devel
mailing list