Commit 125f5b72 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

wined3d: Accelerate texture DISCARD maps as well.

parent aa9b1fb3
...@@ -4618,60 +4618,70 @@ static bool adapter_gl_alloc_bo(struct wined3d_device *device, struct wined3d_re ...@@ -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; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_device_gl *device_gl = wined3d_device_gl(device); 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); wined3d_not_from_cs(device->cs);
assert(device->context_count); assert(device->context_count);
if (resource->type == WINED3D_RTYPE_BUFFER) if (resource->type == WINED3D_RTYPE_BUFFER)
{ {
GLenum usage = GL_STATIC_DRAW; size = resource->size;
struct wined3d_bo_gl *bo_gl; binding = wined3d_buffer_gl_binding_from_bind_flags(gl_info, resource->bind_flags);
bool coherent = true; usage = GL_STATIC_DRAW;
flags = wined3d_resource_gl_storage_flags(resource);
if (resource->usage & WINED3DUSAGE_DYNAMIC) if (resource->usage & WINED3DUSAGE_DYNAMIC)
{ {
usage = GL_STREAM_DRAW_ARB; usage = GL_STREAM_DRAW;
coherent = false; coherent = false;
} }
}
else
{
struct wined3d_texture *texture = texture_from_resource(resource);
if (!(bo_gl = heap_alloc(sizeof(*bo_gl)))) size = texture->sub_resources[sub_resource_idx].size;
return false; 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, if (!(bo_gl = heap_alloc(sizeof(*bo_gl))))
wined3d_buffer_gl_binding_from_bind_flags(gl_info, resource->bind_flags), return false;
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->memory) if (!(wined3d_device_gl_create_bo(device_gl, NULL, size, binding, usage, coherent, flags, bo_gl)))
{ {
struct wined3d_allocator_chunk_gl *chunk = wined3d_allocator_chunk_gl(bo_gl->memory->chunk); 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)) wined3d_allocator_chunk_gl_lock(chunk);
++chunk->c.map_count;
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; wined3d_allocator_chunk_gl_unlock(chunk);
addr->addr = NULL; }
if (!bo_gl->b.map_ptr) addr->buffer_object = &bo_gl->b;
{ addr->addr = NULL;
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 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) static void adapter_gl_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
......
...@@ -1253,41 +1253,51 @@ static bool adapter_vk_alloc_bo(struct wined3d_device *device, struct wined3d_re ...@@ -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_device_vk *device_vk = wined3d_device_vk(device);
struct wined3d_context_vk *context_vk = &device_vk->context_vk; 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); wined3d_not_from_cs(device->cs);
assert(device->context_count); assert(device->context_count);
if (resource->type == WINED3D_RTYPE_BUFFER) 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)))) buffer_usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
return false; 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, if (!(bo_vk = heap_alloc(sizeof(*bo_vk))))
vk_buffer_usage_from_bind_flags(resource->bind_flags), return false;
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->b.map_ptr) if (!(wined3d_context_vk_create_bo(context_vk, size, buffer_usage, memory_type, bo_vk)))
{ {
WARN_(d3d_perf)("BO %p (chunk %p, slab %p) is not mapped.\n", WARN("Failed to create Vulkan buffer.\n");
bo_vk, bo_vk->memory ? bo_vk->memory->chunk : NULL, bo_vk->slab); heap_free(bo_vk);
return false;
}
if (!wined3d_bo_vk_map(bo_vk, context_vk)) if (!bo_vk->b.map_ptr)
ERR("Failed to map bo.\n"); {
} 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; if (!wined3d_bo_vk_map(bo_vk, context_vk))
addr->addr = NULL; ERR("Failed to map bo.\n");
return true;
} }
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) static void adapter_vk_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
......
...@@ -3091,9 +3091,7 @@ static void wined3d_cs_st_finish(struct wined3d_device_context *context, enum wi ...@@ -3091,9 +3091,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, 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) 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 if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
* a texture can be invalidated to even count. */
if (resource->type == WINED3D_RTYPE_BUFFER && (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
{ {
const struct wined3d_d3d_info *d3d_info = &context->device->adapter->d3d_info; const struct wined3d_d3d_info *d3d_info = &context->device->adapter->d3d_info;
struct wined3d_client_resource *client = &resource->client; struct wined3d_client_resource *client = &resource->client;
...@@ -3124,7 +3122,10 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str ...@@ -3124,7 +3122,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)) if (!device->adapter->adapter_ops->adapter_alloc_bo(device, resource, sub_resource_idx, &addr))
return false; 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 else
{ {
......
...@@ -4570,6 +4570,30 @@ void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, ...@@ -4570,6 +4570,30 @@ void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture,
wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location); 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, 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, struct wined3d_context *context, const struct upload_bo *upload_bo, const struct wined3d_box *box,
unsigned int row_pitch, unsigned int slice_pitch) unsigned int row_pitch, unsigned int slice_pitch)
...@@ -4580,6 +4604,15 @@ void wined3d_texture_update_sub_resource(struct wined3d_texture *texture, unsign ...@@ -4580,6 +4604,15 @@ void wined3d_texture_update_sub_resource(struct wined3d_texture *texture, unsign
unsigned int depth = wined3d_texture_get_level_depth(texture, level); unsigned int depth = wined3d_texture_get_level_depth(texture, level);
struct wined3d_box src_box; 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);
/* Try to free address space if we are not mapping persistently. */
wined3d_context_unmap_bo_address(context, (const struct wined3d_bo_address *)&upload_bo->addr, 0, NULL);
}
/* Only load the sub-resource for partial updates. */ /* Only load the sub-resource for partial updates. */
if (!box->left && !box->top && !box->front if (!box->left && !box->top && !box->front
&& box->right == width && box->bottom == height && box->back == depth) && box->right == width && box->bottom == height && box->back == depth)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment