wined3d: Accelerate texture DISCARD maps as well.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
aa9b1fb3a3
commit
125f5b7210
|
@ -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;
|
||||
|
||||
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->memory)
|
||||
{
|
||||
struct wined3d_allocator_chunk_gl *chunk = wined3d_allocator_chunk_gl(bo_gl->memory->chunk);
|
||||
|
||||
wined3d_allocator_chunk_gl_lock(chunk);
|
||||
|
||||
if ((bo_gl->b.map_ptr = chunk->c.map_ptr))
|
||||
++chunk->c.map_count;
|
||||
|
||||
wined3d_allocator_chunk_gl_unlock(chunk);
|
||||
}
|
||||
|
||||
addr->buffer_object = &bo_gl->b;
|
||||
addr->addr = NULL;
|
||||
|
||||
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 true;
|
||||
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;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (!(bo_gl = heap_alloc(sizeof(*bo_gl))))
|
||||
return false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (bo_gl->memory)
|
||||
{
|
||||
struct wined3d_allocator_chunk_gl *chunk = wined3d_allocator_chunk_gl(bo_gl->memory->chunk);
|
||||
|
||||
wined3d_allocator_chunk_gl_lock(chunk);
|
||||
|
||||
if ((bo_gl->b.map_ptr = chunk->c.map_ptr))
|
||||
++chunk->c.map_count;
|
||||
|
||||
wined3d_allocator_chunk_gl_unlock(chunk);
|
||||
}
|
||||
|
||||
addr->buffer_object = &bo_gl->b;
|
||||
addr->addr = NULL;
|
||||
|
||||
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 true;
|
||||
}
|
||||
|
||||
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
|
|||
{
|
||||
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;
|
||||
|
||||
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->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_bo_vk_map(bo_vk, context_vk))
|
||||
ERR("Failed to map bo.\n");
|
||||
}
|
||||
|
||||
addr->buffer_object = &bo_vk->b;
|
||||
addr->addr = NULL;
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (!(bo_vk = heap_alloc(sizeof(*bo_vk))))
|
||||
return false;
|
||||
|
||||
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 (!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_bo_vk_map(bo_vk, context_vk))
|
||||
ERR("Failed to map bo.\n");
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
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;
|
||||
|
@ -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))
|
||||
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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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);
|
||||
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. */
|
||||
if (!box->left && !box->top && !box->front
|
||||
&& box->right == width && box->bottom == height && box->back == depth)
|
||||
|
|
Loading…
Reference in New Issue