Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: New patch.
dlls/wined3d/cs.c | 2 +- dlls/wined3d/surface.c | 15 ++++---- dlls/wined3d/texture.c | 63 ++++++++++++++++++++-------------- dlls/wined3d/wined3d_private.h | 4 +-- 4 files changed, 49 insertions(+), 35 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 81cdb51f207..c65379fe46d 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2673,7 +2673,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * goto error; }
- wined3d_texture_get_memory(src_texture, op->src_sub_resource_idx, &addr, location); + wined3d_texture_get_bo_address(src_texture, op->src_sub_resource_idx, &addr, location); wined3d_texture_get_pitch(src_texture, op->src_sub_resource_idx % src_texture->level_count, &row_pitch, &slice_pitch);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 3309df951dc..8c931d0b225 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -354,7 +354,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr if (!wined3d_texture_load_location(src_texture, sub_resource_idx, context, map_binding)) ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding)); wined3d_texture_get_pitch(src_texture, texture_level, &src_row_pitch, &src_slice_pitch); - wined3d_texture_get_memory(src_texture, sub_resource_idx, &src_data, map_binding); + wined3d_texture_get_bo_address(src_texture, sub_resource_idx, &src_data, map_binding);
if (conv) { @@ -368,7 +368,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr if (!wined3d_texture_load_location(dst_texture, 0, context, map_binding)) ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding)); wined3d_texture_get_pitch(dst_texture, 0, &dst_row_pitch, &dst_slice_pitch); - wined3d_texture_get_memory(dst_texture, 0, &dst_data, map_binding); + wined3d_texture_get_bo_address(dst_texture, 0, &dst_data, map_binding);
src = wined3d_context_map_bo_address(context, &src_data, src_texture->sub_resources[sub_resource_idx].size, WINED3D_MAP_READ); @@ -422,7 +422,8 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i uint8_t *offset; unsigned int i;
- wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location); + /* dst_location was already prepared by the caller. */ + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, dst_location); offset = data.addr;
restore_texture = context->current_rt.texture; @@ -763,7 +764,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int ERR("Failed to load the destination sub-resource into %s.\n", wined3d_debug_location(map_binding)); wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~map_binding); wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch); - wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); + wined3d_texture_get_bo_address(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); dst_map.data = wined3d_context_map_bo_address(context, &dst_data, dst_texture->sub_resources[dst_sub_resource_idx].size, WINED3D_MAP_READ | WINED3D_MAP_WRITE);
@@ -800,7 +801,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int if (!wined3d_texture_load_location(src_texture, src_sub_resource_idx, context, map_binding)) ERR("Failed to load the source sub-resource into %s.\n", wined3d_debug_location(map_binding)); wined3d_texture_get_pitch(src_texture, texture_level, &src_map.row_pitch, &src_map.slice_pitch); - wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &src_data, map_binding); + wined3d_texture_get_bo_address(src_texture, src_sub_resource_idx, &src_data, map_binding); src_map.data = wined3d_context_map_bo_address(context, &src_data, src_texture->sub_resources[src_sub_resource_idx].size, WINED3D_MAP_READ);
@@ -819,7 +820,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int
wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~map_binding); wined3d_texture_get_pitch(dst_texture, texture_level, &dst_map.row_pitch, &dst_map.slice_pitch); - wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); + wined3d_texture_get_bo_address(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); dst_map.data = wined3d_context_map_bo_address(context, &dst_data, dst_texture->sub_resources[dst_sub_resource_idx].size, WINED3D_MAP_WRITE); } @@ -1287,7 +1288,7 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, ERR("Failed to load the sub-resource into %s.\n", wined3d_debug_location(map_binding)); wined3d_texture_invalidate_location(texture, view->sub_resource_idx, ~map_binding); wined3d_texture_get_pitch(texture, level, &map.row_pitch, &map.slice_pitch); - wined3d_texture_get_memory(texture, view->sub_resource_idx, &data, map_binding); + wined3d_texture_get_bo_address(texture, view->sub_resource_idx, &data, map_binding); map.data = wined3d_context_map_bo_address(context, &data, texture->sub_resources[view->sub_resource_idx].size, WINED3D_MAP_WRITE); map.data = (BYTE *)map.data diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 3bbdb492998..35b41a2f70b 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -737,6 +737,32 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture, sub_resource_idx, texture); }
+void wined3d_texture_get_bo_address(const struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_bo_address *data, DWORD location) +{ + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + + if (location == WINED3D_LOCATION_BUFFER) + { + data->addr = NULL; + data->buffer_object = &sub_resource->bo.b; + } + else + { + assert(location == WINED3D_LOCATION_SYSMEM); + if (sub_resource->user_memory) + { + data->addr = sub_resource->user_memory; + } + else + { + data->addr = texture->resource.heap_memory; + data->addr += sub_resource->offset; + } + data->buffer_object = 0; + } +} + void wined3d_texture_clear_dirty_regions(struct wined3d_texture *texture) { unsigned int i; @@ -804,8 +830,8 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture,
if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) return FALSE; - wined3d_texture_get_memory(texture, sub_resource_idx, &source, current); - wined3d_texture_get_memory(texture, sub_resource_idx, &destination, location); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &source, (current & wined3d_texture_sysmem_locations)); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &destination, location); range.offset = 0; range.size = texture->sub_resources[sub_resource_idx].size; wined3d_context_copy_bo_address(context, &destination, &source, 1, &range); @@ -820,34 +846,21 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, return ret; }
-void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, +static void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_bo_address *data, DWORD locations) { - struct wined3d_texture_sub_resource *sub_resource; - TRACE("texture %p, sub_resource_idx %u, data %p, locations %s.\n", texture, sub_resource_idx, data, wined3d_debug_location(locations));
- sub_resource = &texture->sub_resources[sub_resource_idx]; if (locations & WINED3D_LOCATION_BUFFER) { - data->addr = NULL; - data->buffer_object = &sub_resource->bo.b; + wined3d_texture_get_bo_address(texture, sub_resource_idx, data, WINED3D_LOCATION_BUFFER); return; }
if (locations & WINED3D_LOCATION_SYSMEM) { - if (texture->sub_resources[sub_resource_idx].user_memory) - { - data->addr = texture->sub_resources[sub_resource_idx].user_memory; - } - else - { - data->addr = texture->resource.heap_memory; - data->addr += sub_resource->offset; - } - data->buffer_object = 0; + wined3d_texture_get_bo_address(texture, sub_resource_idx, data, WINED3D_LOCATION_SYSMEM); return; }
@@ -1085,7 +1098,7 @@ static void wined3d_texture_create_dc(void *object) } wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding); wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch); - wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, texture->resource.map_binding); if (data.buffer_object) { if (!context) @@ -1158,7 +1171,7 @@ static void wined3d_texture_destroy_dc(void *object) dc_info->dc = NULL; dc_info->bitmap = NULL;
- wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, texture->resource.map_binding); if (data.buffer_object) { context = context_acquire(device, NULL, 0); @@ -2998,7 +3011,7 @@ static BOOL wined3d_texture_gl_load_sysmem(struct wined3d_texture_gl *texture_gl unsigned int src_location;
level = sub_resource_idx % texture_gl->t.level_count; - wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &data, dst_location); + wined3d_texture_get_bo_address(&texture_gl->t, sub_resource_idx, &data, dst_location); src_location = sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB ? WINED3D_LOCATION_TEXTURE_RGB : WINED3D_LOCATION_TEXTURE_SRGB; wined3d_texture_get_level_box(&texture_gl->t, level, &src_box); @@ -3573,7 +3586,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour && (!(flags & WINED3D_MAP_NO_DIRTY_UPDATE) || (resource->usage & WINED3DUSAGE_DYNAMIC))) wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding);
- wined3d_texture_get_memory(texture, sub_resource_idx, &data, resource->map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, resource->map_binding); base_memory = wined3d_context_map_bo_address(context, &data, sub_resource->size, flags); sub_resource->map_flags = flags; TRACE("Base memory pointer %p.\n", base_memory); @@ -3623,7 +3636,7 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso
context = context_acquire(device, NULL, 0);
- wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, texture->resource.map_binding); range.offset = 0; range.size = sub_resource->size; wined3d_context_unmap_bo_address(context, &data, !!(sub_resource->map_flags & WINED3D_MAP_WRITE), &range); @@ -4512,7 +4525,7 @@ void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, context = context_acquire(src_texture->resource.device, NULL, 0);
wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); - wined3d_texture_get_memory(dst_texture, dst_sub_resource_idx, &data, dst_location); + wined3d_texture_get_bo_address(dst_texture, dst_sub_resource_idx, &data, dst_location);
if (src_texture->sub_resources[src_sub_resource_idx].locations & WINED3D_LOCATION_TEXTURE_RGB) src_location = WINED3D_LOCATION_TEXTURE_RGB; @@ -5139,7 +5152,7 @@ static BOOL wined3d_texture_vk_load_sysmem(struct wined3d_texture_vk *texture_vk }
level = sub_resource_idx % texture_vk->t.level_count; - wined3d_texture_get_memory(&texture_vk->t, sub_resource_idx, &data, location); + wined3d_texture_get_bo_address(&texture_vk->t, sub_resource_idx, &data, location); wined3d_texture_get_level_box(&texture_vk->t, level, &src_box); wined3d_texture_get_pitch(&texture_vk->t, level, &row_pitch, &slice_pitch); wined3d_texture_vk_download_data(context, &texture_vk->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 277d5a94fb0..6fd51b77e2a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4625,9 +4625,9 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i void wined3d_texture_cleanup(struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx) DECLSPEC_HIDDEN; +void wined3d_texture_get_bo_address(const struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_bo_address *data, DWORD location) DECLSPEC_HIDDEN; GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) DECLSPEC_HIDDEN; -void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_bo_address *data, DWORD locations) DECLSPEC_HIDDEN; void wined3d_texture_invalidate_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN; void wined3d_texture_load(struct wined3d_texture *texture,
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: New patch.
dlls/wined3d/texture.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 35b41a2f70b..b6908dac891 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -847,8 +847,11 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, }
static void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_bo_address *data, DWORD locations) + struct wined3d_bo_address *data) { + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + DWORD locations = sub_resource->locations; + TRACE("texture %p, sub_resource_idx %u, data %p, locations %s.\n", texture, sub_resource_idx, data, wined3d_debug_location(locations));
@@ -3227,7 +3230,7 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g wined3d_texture_set_map_binding(&texture_gl->t, WINED3D_LOCATION_SYSMEM); }
- wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &data, sub_resource->locations); + wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &data); if (conversion) { width = src_box.right - src_box.left; @@ -4497,8 +4500,7 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
src_level = src_sub_resource_idx % src_texture->level_count; - wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data, - src_texture->sub_resources[src_sub_resource_idx].locations); + wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data); wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch);
dst_texture->texture_ops->texture_upload_data(context, wined3d_const_bo_address(&data), @@ -5126,7 +5128,7 @@ static BOOL wined3d_texture_vk_load_texture(struct wined3d_texture_vk *texture_v }
level = sub_resource_idx % texture_vk->t.level_count; - wined3d_texture_get_memory(&texture_vk->t, sub_resource_idx, &data, sub_resource->locations); + wined3d_texture_get_memory(&texture_vk->t, sub_resource_idx, &data); wined3d_texture_get_level_box(&texture_vk->t, level, &src_box); wined3d_texture_get_pitch(&texture_vk->t, level, &row_pitch, &slice_pitch); wined3d_texture_vk_upload_data(context, wined3d_const_bo_address(&data), texture_vk->t.resource.format,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: Validate WINED3D_LOCATION_SYSMEM, and return immediately if we are trying to load SYSMEM.
dlls/wined3d/texture.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index b6908dac891..6a11f613732 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -815,6 +815,23 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, return TRUE; }
+ if (current & WINED3D_LOCATION_CLEARED) + { + struct wined3d_bo_address addr; + + /* FIXME: Clear textures on the GPU if possible. */ + + if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) + return FALSE; + wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size); + wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); + current |= WINED3D_LOCATION_SYSMEM; + + if (current & location) + return TRUE; + } + if (!current) { ERR("Sub-resource %u of texture %p does not have any up to date location.\n",
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: New patch.
dlls/wined3d/texture.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 6a11f613732..00146cf32d1 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -864,14 +864,24 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, }
static void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, - struct wined3d_bo_address *data) + struct wined3d_context *context, struct wined3d_bo_address *data) { struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; DWORD locations = sub_resource->locations;
- TRACE("texture %p, sub_resource_idx %u, data %p, locations %s.\n", - texture, sub_resource_idx, data, wined3d_debug_location(locations)); + TRACE("texture %p, context %p, sub_resource_idx %u, data %p, locations %s.\n", + texture, context, sub_resource_idx, data, wined3d_debug_location(locations));
+ if (locations & (WINED3D_LOCATION_DISCARDED | WINED3D_LOCATION_CLEARED)) + { + locations = (wined3d_texture_use_pbo(texture, context->d3d_info) ? WINED3D_LOCATION_BUFFER : WINED3D_LOCATION_SYSMEM); + if (!wined3d_texture_load_location(texture, sub_resource_idx, context, locations)) + { + data->buffer_object = 0; + data->addr = NULL; + return; + } + } if (locations & WINED3D_LOCATION_BUFFER) { wined3d_texture_get_bo_address(texture, sub_resource_idx, data, WINED3D_LOCATION_BUFFER); @@ -3247,7 +3257,7 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g wined3d_texture_set_map_binding(&texture_gl->t, WINED3D_LOCATION_SYSMEM); }
- wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &data); + wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &context_gl->c, &data); if (conversion) { width = src_box.right - src_box.left; @@ -4517,7 +4527,7 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
src_level = src_sub_resource_idx % src_texture->level_count; - wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data); + wined3d_texture_get_memory(src_texture, src_sub_resource_idx, context, &data); wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch);
dst_texture->texture_ops->texture_upload_data(context, wined3d_const_bo_address(&data), @@ -5145,7 +5155,7 @@ static BOOL wined3d_texture_vk_load_texture(struct wined3d_texture_vk *texture_v }
level = sub_resource_idx % texture_vk->t.level_count; - wined3d_texture_get_memory(&texture_vk->t, sub_resource_idx, &data); + wined3d_texture_get_memory(&texture_vk->t, sub_resource_idx, context, &data); wined3d_texture_get_level_box(&texture_vk->t, level, &src_box); wined3d_texture_get_pitch(&texture_vk->t, level, &row_pitch, &slice_pitch); wined3d_texture_vk_upload_data(context, wined3d_const_bo_address(&data), texture_vk->t.resource.format,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
For the purposes of texture2d_blt(). The main goal here is to allow uploading from WINED3D_LOCATION_CLEARED to a multisample texture (and hence initializing it).
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: New patch.
dlls/wined3d/surface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 8c931d0b225..f9cc2a1cf0c 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -32,7 +32,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
-static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_BUFFER; +static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM + | WINED3D_LOCATION_BUFFER | WINED3D_LOCATION_CLEARED;
/* Works correctly only for <= 4 bpp formats. */ static void get_color_masks(const struct wined3d_format *format, uint32_t *masks)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: No changes.
dlls/wined3d/texture.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 00146cf32d1..13c26692f77 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -3918,16 +3918,6 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc if (wined3d_texture_use_pbo(texture, d3d_info)) texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
- if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D - || !wined3d_texture_use_pbo(texture, d3d_info)) - { - if (!wined3d_resource_prepare_sysmem(&texture->resource)) - { - wined3d_texture_cleanup_sync(texture); - return E_OUTOFMEMORY; - } - } - sub_count = level_count * layer_count; if (sub_count / layer_count != level_count) { @@ -3956,12 +3946,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc struct wined3d_texture_sub_resource *sub_resource;
sub_resource = &texture->sub_resources[i]; - sub_resource->locations = WINED3D_LOCATION_DISCARDED; - if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D) - { - wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_SYSMEM); - wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM); - } + sub_resource->locations = WINED3D_LOCATION_CLEARED;
if (FAILED(hr = device_parent->ops->texture_sub_resource_created(device_parent, desc->resource_type, texture, i, &sub_resource->parent, &sub_resource->parent_ops)))
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: Fix a leak introduced in wined3d_texture_remove_buffer_object().
dlls/wined3d/texture.c | 45 +++++++++++++++++++++++++--------- dlls/wined3d/wined3d_private.h | 7 +----- 2 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 13c26692f77..75997914d77 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -745,7 +745,7 @@ void wined3d_texture_get_bo_address(const struct wined3d_texture *texture, if (location == WINED3D_LOCATION_BUFFER) { data->addr = NULL; - data->buffer_object = &sub_resource->bo.b; + data->buffer_object = sub_resource->bo; } else { @@ -903,12 +903,15 @@ static void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl) { - struct wined3d_bo_gl *bo = &texture->sub_resources[sub_resource_idx].bo.gl; + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; + struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(sub_resource->bo);
TRACE("texture %p, sub_resource_idx %u, context_gl %p.\n", texture, sub_resource_idx, context_gl);
- wined3d_context_gl_destroy_bo(context_gl, bo); + wined3d_context_gl_destroy_bo(context_gl, bo_gl); wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_BUFFER); + sub_resource->bo = NULL; + heap_free(bo_gl); }
static void wined3d_texture_unload_location(struct wined3d_texture *texture, @@ -2059,16 +2062,23 @@ static void wined3d_texture_gl_prepare_buffer_object(struct wined3d_texture_gl * struct wined3d_bo_gl *bo;
sub_resource = &texture_gl->t.sub_resources[sub_resource_idx]; - bo = &sub_resource->bo.gl; - if (bo->id) + + if (sub_resource->bo) + return; + + if (!(bo = heap_alloc(sizeof(*bo)))) return;
if (!wined3d_device_gl_create_bo(wined3d_device_gl(texture_gl->t.resource.device), context_gl, sub_resource->size, GL_PIXEL_UNPACK_BUFFER, GL_STREAM_DRAW, true, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_CLIENT_STORAGE_BIT, bo)) + { + heap_free(bo); return; + }
TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", bo->id, texture_gl, sub_resource_idx); + sub_resource->bo = &bo->b; }
static void wined3d_texture_force_reload(struct wined3d_texture *texture) @@ -3249,7 +3259,7 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g /* Don't use PBOs for converted surfaces. During PBO conversion we look at * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is * getting called. */ - if (conversion && sub_resource->bo.gl.id) + if (conversion && sub_resource->bo) { TRACE("Removing the pbo attached to texture %p, %u.\n", texture_gl, sub_resource_idx);
@@ -3386,7 +3396,7 @@ static void wined3d_texture_gl_unload_location(struct wined3d_texture *texture, sub_count = texture->level_count * texture->layer_count; for (i = 0; i < sub_count; ++i) { - if (texture_gl->t.sub_resources[i].bo.gl.id) + if (texture_gl->t.sub_resources[i].bo) wined3d_texture_remove_buffer_object(&texture_gl->t, i, context_gl); } break; @@ -5294,18 +5304,24 @@ static BOOL wined3d_texture_vk_prepare_buffer_object(struct wined3d_texture_vk * struct wined3d_bo_vk *bo;
sub_resource = &texture_vk->t.sub_resources[sub_resource_idx]; - bo = &sub_resource->bo.vk; - if (bo->vk_buffer) + if (sub_resource->bo) return TRUE;
+ if (!(bo = heap_alloc(sizeof(*bo)))) + return FALSE; + if (!wined3d_context_vk_create_bo(context_vk, sub_resource->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bo)) + { + heap_free(bo); return FALSE; + }
/* Texture buffer objects receive a barrier to HOST_READ in wined3d_texture_vk_download_data(), * so they don't need it when they are mapped for reading. */ bo->host_synced = true; + sub_resource->bo = &bo->b; TRACE("Created buffer object %p for texture %p, sub-resource %u.\n", bo, texture_vk, sub_resource_idx); return TRUE; } @@ -5380,10 +5396,15 @@ static void wined3d_texture_vk_unload_location(struct wined3d_texture *texture, sub_count = texture->level_count * texture->layer_count; for (i = 0; i < sub_count; ++i) { - if (texture->sub_resources[i].bo.vk.vk_buffer) + struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[i]; + + if (sub_resource->bo) { - wined3d_context_vk_destroy_bo(context_vk, &texture->sub_resources[i].bo.vk); - texture->sub_resources[i].bo.vk.vk_buffer = VK_NULL_HANDLE; + struct wined3d_bo_vk *bo_vk = wined3d_bo_vk(sub_resource->bo); + + wined3d_context_vk_destroy_bo(context_vk, bo_vk); + heap_free(bo_vk); + sub_resource->bo = NULL; } } break; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 6fd51b77e2a..a9837911ea6 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4532,12 +4532,7 @@ struct wined3d_texture unsigned int map_count; uint32_t map_flags; DWORD locations; - union - { - struct wined3d_bo b; - struct wined3d_bo_gl gl; - struct wined3d_bo_vk vk; - } bo; + struct wined3d_bo *bo;
void *user_memory; } *sub_resources;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: Try to unmap after renaming.
dlls/wined3d/adapter_gl.c | 76 ++++++++++++++++++++++----------------- dlls/wined3d/adapter_vk.c | 54 ++++++++++++++++------------ dlls/wined3d/cs.c | 9 ++--- dlls/wined3d/texture.c | 33 +++++++++++++++++ 4 files changed, 113 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 c65379fe46d..f0328f82794 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 75997914d77..003aca3aecb 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -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)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com