[PATCH 5/5] wined3d: Accelerate texture DISCARD maps as well.
Zebediah Figura
zfigura at codeweavers.com
Sun Feb 20 23:22:25 CST 2022
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 76 ++++++++++++++++++++++-----------------
dlls/wined3d/adapter_vk.c | 54 ++++++++++++++++------------
dlls/wined3d/cs.c | 9 ++---
dlls/wined3d/texture.c | 31 ++++++++++++++++
4 files changed, 111 insertions(+), 59 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 4e93e25452d..6247f60716f 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4618,60 +4618,70 @@ static bool adapter_gl_alloc_bo(struct wined3d_device *device, struct wined3d_re
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_device_gl *device_gl = wined3d_device_gl(device);
+ struct wined3d_bo_gl *bo_gl;
+ GLenum binding, usage;
+ bool coherent = true;
+ GLbitfield flags;
+ GLsizeiptr size;
wined3d_not_from_cs(device->cs);
assert(device->context_count);
if (resource->type == WINED3D_RTYPE_BUFFER)
{
- GLenum usage = GL_STATIC_DRAW;
- struct wined3d_bo_gl *bo_gl;
- bool coherent = true;
-
+ size = resource->size;
+ binding = wined3d_buffer_gl_binding_from_bind_flags(gl_info, resource->bind_flags);
+ usage = GL_STATIC_DRAW;
+ flags = wined3d_resource_gl_storage_flags(resource);
if (resource->usage & WINED3DUSAGE_DYNAMIC)
{
- usage = GL_STREAM_DRAW_ARB;
+ usage = GL_STREAM_DRAW;
coherent = false;
}
+ }
+ else
+ {
+ struct wined3d_texture *texture = texture_from_resource(resource);
- if (!(bo_gl = heap_alloc(sizeof(*bo_gl))))
- return false;
+ size = texture->sub_resources[sub_resource_idx].size;
+ binding = GL_PIXEL_UNPACK_BUFFER;
+ usage = GL_STREAM_DRAW;
+ flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_CLIENT_STORAGE_BIT;
+ }
- if (!(wined3d_device_gl_create_bo(device_gl, NULL, resource->size,
- wined3d_buffer_gl_binding_from_bind_flags(gl_info, resource->bind_flags),
- usage, coherent, wined3d_resource_gl_storage_flags(resource), bo_gl)))
- {
- WARN("Failed to create OpenGL buffer.\n");
- heap_free(bo_gl);
- return false;
- }
+ if (!(bo_gl = heap_alloc(sizeof(*bo_gl))))
+ return false;
- if (bo_gl->memory)
- {
- struct wined3d_allocator_chunk_gl *chunk = wined3d_allocator_chunk_gl(bo_gl->memory->chunk);
+ if (!(wined3d_device_gl_create_bo(device_gl, NULL, size, binding, usage, coherent, flags, bo_gl)))
+ {
+ WARN("Failed to create OpenGL buffer.\n");
+ heap_free(bo_gl);
+ return false;
+ }
- wined3d_allocator_chunk_gl_lock(chunk);
+ if (bo_gl->memory)
+ {
+ struct wined3d_allocator_chunk_gl *chunk = wined3d_allocator_chunk_gl(bo_gl->memory->chunk);
- if ((bo_gl->b.map_ptr = chunk->c.map_ptr))
- ++chunk->c.map_count;
+ wined3d_allocator_chunk_gl_lock(chunk);
- wined3d_allocator_chunk_gl_unlock(chunk);
- }
+ if ((bo_gl->b.map_ptr = chunk->c.map_ptr))
+ ++chunk->c.map_count;
- addr->buffer_object = &bo_gl->b;
- addr->addr = NULL;
+ wined3d_allocator_chunk_gl_unlock(chunk);
+ }
- if (!bo_gl->b.map_ptr)
- {
- WARN_(d3d_perf)("BO %p (chunk %p) is not persistently mapped.\n",
- bo_gl, bo_gl->memory ? bo_gl->memory->chunk : NULL);
- wined3d_cs_map_bo_address(device->cs, addr, resource->size, WINED3D_MAP_WRITE | WINED3D_MAP_DISCARD);
- }
+ addr->buffer_object = &bo_gl->b;
+ addr->addr = NULL;
- return true;
+ if (!bo_gl->b.map_ptr)
+ {
+ WARN_(d3d_perf)("BO %p (chunk %p) is not persistently mapped.\n",
+ bo_gl, bo_gl->memory ? bo_gl->memory->chunk : NULL);
+ wined3d_cs_map_bo_address(device->cs, addr, resource->size, WINED3D_MAP_WRITE | WINED3D_MAP_DISCARD);
}
- return false;
+ return true;
}
static void adapter_gl_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 9b9b399a810..72f945bddb0 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1253,41 +1253,51 @@ static bool adapter_vk_alloc_bo(struct wined3d_device *device, struct wined3d_re
{
struct wined3d_device_vk *device_vk = wined3d_device_vk(device);
struct wined3d_context_vk *context_vk = &device_vk->context_vk;
+ VkMemoryPropertyFlags memory_type;
+ VkBufferUsageFlags buffer_usage;
+ struct wined3d_bo_vk *bo_vk;
+ VkDeviceSize size;
wined3d_not_from_cs(device->cs);
assert(device->context_count);
if (resource->type == WINED3D_RTYPE_BUFFER)
{
- struct wined3d_bo_vk *bo_vk;
+ buffer_usage = vk_buffer_usage_from_bind_flags(resource->bind_flags);
+ memory_type = vk_memory_type_from_access_flags(resource->access, resource->usage);
+ size = resource->size;
+ }
+ else
+ {
+ struct wined3d_texture *texture = texture_from_resource(resource);
- if (!(bo_vk = heap_alloc(sizeof(*bo_vk))))
- return false;
+ buffer_usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ memory_type = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ size = texture->sub_resources[sub_resource_idx].size;
+ }
- if (!(wined3d_context_vk_create_bo(context_vk, resource->size,
- vk_buffer_usage_from_bind_flags(resource->bind_flags),
- vk_memory_type_from_access_flags(resource->access, resource->usage), bo_vk)))
- {
- WARN("Failed to create Vulkan buffer.\n");
- heap_free(bo_vk);
- return false;
- }
+ if (!(bo_vk = heap_alloc(sizeof(*bo_vk))))
+ return false;
- if (!bo_vk->b.map_ptr)
- {
- WARN_(d3d_perf)("BO %p (chunk %p, slab %p) is not mapped.\n",
- bo_vk, bo_vk->memory ? bo_vk->memory->chunk : NULL, bo_vk->slab);
+ if (!(wined3d_context_vk_create_bo(context_vk, size, buffer_usage, memory_type, bo_vk)))
+ {
+ WARN("Failed to create Vulkan buffer.\n");
+ heap_free(bo_vk);
+ return false;
+ }
- if (!wined3d_bo_vk_map(bo_vk, context_vk))
- ERR("Failed to map bo.\n");
- }
+ if (!bo_vk->b.map_ptr)
+ {
+ WARN_(d3d_perf)("BO %p (chunk %p, slab %p) is not mapped.\n",
+ bo_vk, bo_vk->memory ? bo_vk->memory->chunk : NULL, bo_vk->slab);
- addr->buffer_object = &bo_vk->b;
- addr->addr = NULL;
- return true;
+ if (!wined3d_bo_vk_map(bo_vk, context_vk))
+ ERR("Failed to map bo.\n");
}
- return false;
+ addr->buffer_object = &bo_vk->b;
+ addr->addr = NULL;
+ return true;
}
static void adapter_vk_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 81cdb51f207..f0384748105 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -3093,9 +3093,7 @@ static void wined3d_cs_st_finish(struct wined3d_device_context *context, enum wi
static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, struct wined3d_resource *resource,
unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, uint32_t flags)
{
- /* Limit NOOVERWRITE maps to buffers for now; there are too many ways that
- * a texture can be invalidated to even count. */
- if (resource->type == WINED3D_RTYPE_BUFFER && (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
+ if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
{
const struct wined3d_d3d_info *d3d_info = &context->device->adapter->d3d_info;
struct wined3d_client_resource *client = &resource->client;
@@ -3126,7 +3124,10 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str
if (!device->adapter->adapter_ops->adapter_alloc_bo(device, resource, sub_resource_idx, &addr))
return false;
- client->addr = addr;
+ /* Limit NOOVERWRITE maps to buffers for now; there are too many
+ * ways that a texture can be invalidated to even count. */
+ if (resource->type == WINED3D_RTYPE_BUFFER)
+ client->addr = addr;
}
else
{
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 9b32b9f3d1a..6905dd4c2a9 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -4539,6 +4539,30 @@ void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture,
wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location);
}
+static void wined3d_texture_set_bo(struct wined3d_texture *texture,
+ unsigned sub_resource_idx, struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
+ struct wined3d_bo *prev_bo = sub_resource->bo;
+
+ TRACE("texture %p, sub_resource_idx %u, context %p, bo %p.\n", texture, sub_resource_idx, context, bo);
+
+ if (prev_bo)
+ {
+ struct wined3d_bo_user *bo_user;
+
+ LIST_FOR_EACH_ENTRY(bo_user, &prev_bo->users, struct wined3d_bo_user, entry)
+ bo_user->valid = false;
+ assert(list_empty(&bo->users));
+ list_move_head(&bo->users, &prev_bo->users);
+
+ wined3d_context_destroy_bo(context, prev_bo);
+ heap_free(prev_bo);
+ }
+
+ sub_resource->bo = bo;
+}
+
void wined3d_texture_update_sub_resource(struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_context *context, const struct upload_bo *upload_bo, const struct wined3d_box *box,
unsigned int row_pitch, unsigned int slice_pitch)
@@ -4549,6 +4573,13 @@ void wined3d_texture_update_sub_resource(struct wined3d_texture *texture, unsign
unsigned int depth = wined3d_texture_get_level_depth(texture, level);
struct wined3d_box src_box;
+ if (upload_bo->flags & UPLOAD_BO_RENAME_ON_UNMAP)
+ {
+ wined3d_texture_set_bo(texture, sub_resource_idx, context, upload_bo->addr.buffer_object);
+ wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER);
+ wined3d_texture_invalidate_location(texture, sub_resource_idx, ~WINED3D_LOCATION_BUFFER);
+ }
+
/* Only load the sub-resource for partial updates. */
if (!box->left && !box->top && !box->front
&& box->right == width && box->bottom == height && box->back == depth)
--
2.34.1
More information about the wine-devel
mailing list