Stop changing their attributes in place. This is complex, somewhat brittle, and currently broken for the Vulkan backend.
Restrict wined3d_texture_update_desc() to changing user memory and pitch.
-- v2: wined3d: Remove no longer used arguments from wined3d_texture_update_desc().
From: Zebediah Figura zfigura@codeweavers.com
For ddraw. --- dlls/wined3d/swapchain.c | 7 +++++++ dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 1 + 3 files changed, 9 insertions(+)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 337c0410d39..c280c42e582 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -275,6 +275,13 @@ struct wined3d_texture * CDECL wined3d_swapchain_get_back_buffer(const struct wi return swapchain->back_buffers[back_buffer_idx]; }
+struct wined3d_texture * CDECL wined3d_swapchain_get_front_buffer(const struct wined3d_swapchain *swapchain) +{ + TRACE("swapchain %p.\n", swapchain); + + return swapchain->front_buffer; +} + struct wined3d_output * wined3d_swapchain_get_output(const struct wined3d_swapchain *swapchain) { TRACE("swapchain %p.\n", swapchain); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 8560c1a1bb6..18035d2cb16 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -270,6 +270,7 @@ @ cdecl wined3d_swapchain_get_desc(ptr ptr) @ cdecl wined3d_swapchain_get_device(ptr) @ cdecl wined3d_swapchain_get_display_mode(ptr ptr ptr) +@ cdecl wined3d_swapchain_get_front_buffer(ptr) @ cdecl wined3d_swapchain_get_front_buffer_data(ptr ptr long) @ cdecl wined3d_swapchain_get_gamma_ramp(ptr ptr) @ cdecl wined3d_swapchain_get_parent(ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 0e921a9a6ad..32a1a70b040 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2809,6 +2809,7 @@ struct wined3d_texture * __cdecl wined3d_swapchain_get_back_buffer(const struct struct wined3d_device * __cdecl wined3d_swapchain_get_device(const struct wined3d_swapchain *swapchain); HRESULT __cdecl wined3d_swapchain_get_display_mode(const struct wined3d_swapchain *swapchain, struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation); +struct wined3d_texture * __cdecl wined3d_swapchain_get_front_buffer(const struct wined3d_swapchain *swapchain); HRESULT __cdecl wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapchain *swapchain, struct wined3d_texture *dst_texture, unsigned int sub_resource_idx); HRESULT __cdecl wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *swapchain,
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ddraw/ddraw.c | 24 ++---------------------- dlls/ddraw/ddraw_private.h | 1 - dlls/ddraw/surface.c | 2 +- 3 files changed, 3 insertions(+), 24 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index d6570739a51..c56226fb71d 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -938,7 +938,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, }
rtv = wined3d_device_context_get_rendertarget_view(ddraw->immediate_context, 0); - /* Rendering to ddraw->wined3d_frontbuffer. */ + /* Rendering to the wined3d frontbuffer. */ if (rtv && !wined3d_rendertarget_view_get_sub_resource_parent(rtv)) rtv = NULL; else if (rtv) @@ -5042,43 +5042,23 @@ static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_d return DD_OK; }
-static void STDMETHODCALLTYPE ddraw_frontbuffer_destroyed(void *parent) -{ - struct ddraw *ddraw = parent; - ddraw->wined3d_frontbuffer = NULL; -} - -static const struct wined3d_parent_ops ddraw_frontbuffer_parent_ops = -{ - ddraw_frontbuffer_destroyed, -}; - static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent, void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags, struct wined3d_texture **texture) { struct ddraw *ddraw = ddraw_from_device_parent(device_parent); - const struct wined3d_parent_ops *parent_ops; HRESULT hr;
TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#lx, texture %p.\n", device_parent, container_parent, desc, texture_flags, texture);
- if (!ddraw->wined3d_frontbuffer) - parent_ops = &ddraw_frontbuffer_parent_ops; - else - parent_ops = &ddraw_null_wined3d_parent_ops; - if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, 1, - texture_flags, NULL, ddraw, parent_ops, texture))) + texture_flags, NULL, ddraw, &ddraw_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#lx.\n", hr); return hr; }
- if (!ddraw->wined3d_frontbuffer) - ddraw->wined3d_frontbuffer = *texture; - return hr; }
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 1be3df5f2c9..a3f309f89f0 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -103,7 +103,6 @@ struct ddraw
struct ddraw_surface *primary; RECT primary_lock; - struct wined3d_texture *wined3d_frontbuffer; struct wined3d_texture *gdi_surface; struct wined3d_swapchain *wined3d_swapchain; struct wined3d_swapchain_state_parent state_parent; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index b601104049f..52ca900441c 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -133,7 +133,7 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, if (swap_interval) dst_texture = wined3d_swapchain_get_back_buffer(ddraw->wined3d_swapchain, 0); else - dst_texture = ddraw->wined3d_frontbuffer; + dst_texture = wined3d_swapchain_get_front_buffer(ddraw->wined3d_swapchain);
if (SUCCEEDED(hr = wined3d_device_context_blt(ddraw->immediate_context, dst_texture, 0, rect, ddraw_surface_get_any_texture(surface, DDRAW_SURFACE_READ), surface->sub_resource_idx, rect, 0,
From: Zebediah Figura zfigura@codeweavers.com
Instead of using wined3d_texture_update_desc(). This is safe, because:
* ddraw never exposes wined3d textures directly, and always retrieves them directly from wined3d when rendering.
* d3d8 and d3d9 (non-extended) will only resize buffers during a reset, and resetting is forbidden if the application holds any references to the backbuffers. RTVs are also replaced during a reset, so there is no concern about retrieving the old RTVs from the device state.
* d3d9ex allows resetting while holding references to the backbuffers, but tests (fixed by this patch) show that the backbuffers should in fact be recreated.
* dxgi forbids holding references to back buffers during ResizeBuffers(), including indirect references via command lists or device contexts. --- dlls/d3d9/tests/d3d9ex.c | 6 ++--- dlls/wined3d/swapchain.c | 55 ++++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c index 41f930a2408..3cb21f1ff38 100644 --- a/dlls/d3d9/tests/d3d9ex.c +++ b/dlls/d3d9/tests/d3d9ex.c @@ -3875,14 +3875,14 @@ static void test_backbuffer_resize(void) old_backbuffer = backbuffer; hr = IDirect3DSurface9_GetDesc(old_backbuffer, &surface_desc); ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#lx.\n", hr); - todo_wine ok(surface_desc.Width == 640, "Got unexpected width %u.\n", surface_desc.Width); - todo_wine ok(surface_desc.Height == 480, "Got unexpected height %u.\n", surface_desc.Height); + ok(surface_desc.Width == 640, "Got unexpected width %u.\n", surface_desc.Width); + ok(surface_desc.Height == 480, "Got unexpected height %u.\n", surface_desc.Height); refcount = IDirect3DSurface9_Release(old_backbuffer); ok(!refcount, "Surface has %lu references left.\n", refcount);
hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr); - todo_wine ok(backbuffer != old_backbuffer, "Expected new backbuffer surface.\n"); + ok(backbuffer != old_backbuffer, "Expected new backbuffer surface.\n");
hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer); ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index c280c42e582..5638c80b538 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1911,12 +1911,46 @@ void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activa wined3d_filter_messages(window, filter); }
+static HRESULT recreate_texture(struct wined3d_texture **texture_ptr, struct wined3d_swapchain *swapchain) +{ + const struct wined3d_swapchain_desc *swapchain_desc = &swapchain->state.desc; + struct wined3d_texture *old_texture = *texture_ptr; + struct wined3d_device *device = swapchain->device; + struct wined3d_resource_desc texture_desc; + struct wined3d_texture *new_texture; + unsigned int texture_flags = 0; + HRESULT hr; + + wined3d_resource_get_desc(&old_texture->resource, &texture_desc); + + texture_desc.width = swapchain_desc->backbuffer_width; + texture_desc.height = swapchain_desc->backbuffer_height; + texture_desc.format = swapchain_desc->backbuffer_format; + texture_desc.multisample_type = swapchain_desc->multisample_type; + texture_desc.multisample_quality = swapchain_desc->multisample_quality; + + if (swapchain_desc->flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) + texture_flags |= WINED3D_TEXTURE_CREATE_GET_DC; + + if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent, swapchain->parent, + &texture_desc, texture_flags, &new_texture))) + { + ERR("Failed to recreate swapchain texture, hr %#lx.\n", hr); + return hr; + } + + wined3d_texture_set_swapchain(new_texture, swapchain); + *texture_ptr = new_texture; + + return S_OK; +} + HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count, unsigned int width, unsigned int height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality) { struct wined3d_swapchain_desc *desc = &swapchain->state.desc; - BOOL update_desc = FALSE; + bool recreate = false;
TRACE("swapchain %p, buffer_count %u, width %u, height %u, format %s, " "multisample_type %#x, multisample_quality %#x.\n", @@ -1955,7 +1989,7 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha { desc->backbuffer_width = width; desc->backbuffer_height = height; - update_desc = TRUE; + recreate = true; }
if (format_id == WINED3DFMT_UNKNOWN) @@ -1968,7 +2002,7 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha if (format_id != desc->backbuffer_format) { desc->backbuffer_format = format_id; - update_desc = TRUE; + recreate = true; }
if (multisample_type != desc->multisample_type @@ -1976,24 +2010,23 @@ HRESULT CDECL wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapcha { desc->multisample_type = multisample_type; desc->multisample_quality = multisample_quality; - update_desc = TRUE; + recreate = true; }
- if (update_desc) + if (recreate) { HRESULT hr; UINT i;
- if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, 0, desc->backbuffer_width, - desc->backbuffer_height, desc->backbuffer_format, - desc->multisample_type, desc->multisample_quality, NULL, 0))) + if (FAILED(hr = recreate_texture(&swapchain->front_buffer, swapchain))) return hr;
+ wined3d_texture_validate_location(swapchain->front_buffer, 0, WINED3D_LOCATION_DRAWABLE); + wined3d_texture_invalidate_location(swapchain->front_buffer, 0, ~WINED3D_LOCATION_DRAWABLE); + for (i = 0; i < desc->backbuffer_count; ++i) { - if (FAILED(hr = wined3d_texture_update_desc(swapchain->back_buffers[i], 0, desc->backbuffer_width, - desc->backbuffer_height, desc->backbuffer_format, - desc->multisample_type, desc->multisample_quality, NULL, 0))) + if (FAILED(hr = recreate_texture(&swapchain->back_buffers[i], swapchain))) return hr; } }
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/cs.c | 5 ++-- dlls/wined3d/surface.c | 26 +++++++++---------- dlls/wined3d/texture.c | 47 +++++++++++++++++----------------- dlls/wined3d/wined3d_private.h | 5 ++-- 4 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index bca0b017c1f..e938a0e1df7 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2594,9 +2594,8 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * return; }
- 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); + wined3d_texture_get_bo_address(src_texture, op->src_sub_resource_idx, + &addr, &row_pitch, &slice_pitch, location);
dst_texture->texture_ops->texture_upload_data(context, wined3d_const_bo_address(&addr), dst_texture->resource.format, &op->src_box, row_pitch, slice_pitch, dst_texture, diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index fd8db9ce60d..24a08e3a797 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -289,8 +289,8 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr map_binding = src_texture->resource.map_binding; 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_bo_address(src_texture, sub_resource_idx, &src_data, map_binding); + wined3d_texture_get_bo_address(src_texture, sub_resource_idx, + &src_data, &src_row_pitch, &src_slice_pitch, map_binding);
if (conv) { @@ -303,8 +303,7 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr map_binding = dst_texture->resource.map_binding; 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_bo_address(dst_texture, 0, &dst_data, map_binding); + wined3d_texture_get_bo_address(dst_texture, 0, &dst_data, &dst_row_pitch, &dst_slice_pitch, map_binding);
src = wined3d_context_map_bo_address(context, &src_data, src_texture->sub_resources[sub_resource_idx].size, WINED3D_MAP_READ); @@ -359,7 +358,7 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i unsigned int i;
/* dst_location was already prepared by the caller. */ - wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, dst_location); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, &row_pitch, &slice_pitch, dst_location); offset = data.addr;
restore_texture = context->current_rt.texture; @@ -418,7 +417,6 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i }
level = sub_resource_idx % texture->level_count; - wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch); format_gl = wined3d_format_gl(resource->format);
/* Setup pixel store pack state -- to glReadPixels into the correct place */ @@ -699,8 +697,8 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int if (!wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, map_binding)) 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_bo_address(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); + wined3d_texture_get_bo_address(dst_texture, dst_sub_resource_idx, + &dst_data, &dst_map.row_pitch, &dst_map.slice_pitch, 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);
@@ -736,8 +734,8 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int texture_level = src_sub_resource_idx % src_texture->level_count; 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_bo_address(src_texture, src_sub_resource_idx, &src_data, map_binding); + wined3d_texture_get_bo_address(src_texture, src_sub_resource_idx, + &src_data, &src_map.row_pitch, &src_map.slice_pitch, 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);
@@ -755,8 +753,8 @@ 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_bo_address(dst_texture, dst_sub_resource_idx, &dst_data, map_binding); + wined3d_texture_get_bo_address(dst_texture, dst_sub_resource_idx, + &dst_data, &dst_map.row_pitch, &dst_map.slice_pitch, 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); } @@ -1219,8 +1217,8 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, if (!wined3d_texture_load_location(texture, view->sub_resource_idx, context, map_binding)) 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_bo_address(texture, view->sub_resource_idx, &data, map_binding); + wined3d_texture_get_bo_address(texture, view->sub_resource_idx, &data, + &map.row_pitch, &map.slice_pitch, map_binding); map.data = wined3d_context_map_bo_address(context, &data, texture->sub_resources[view->sub_resource_idx].size, WINED3D_MAP_WRITE); range.offset = 0; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 626b0908c68..5f639ff4326 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -733,8 +733,8 @@ 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, uint32_t location) +void wined3d_texture_get_bo_address(const struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_bo_address *data, unsigned int *row_pitch, unsigned int *slice_pitch, uint32_t location) { struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
@@ -757,6 +757,9 @@ void wined3d_texture_get_bo_address(const struct wined3d_texture *texture, } data->buffer_object = 0; } + + if (row_pitch) + wined3d_texture_get_pitch(texture, sub_resource_idx % texture->level_count, row_pitch, slice_pitch); }
void wined3d_texture_clear_dirty_regions(struct wined3d_texture *texture) @@ -823,11 +826,12 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, && (current & (wined3d_texture_sysmem_locations | WINED3D_LOCATION_CLEARED))) { struct wined3d_bo_address source, destination; + unsigned int row_pitch, slice_pitch; struct wined3d_range range;
if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) return FALSE; - wined3d_texture_get_bo_address(texture, sub_resource_idx, &destination, location); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &destination, &row_pitch, &slice_pitch, location); range.offset = 0; range.size = texture->sub_resources[sub_resource_idx].size; if (current & WINED3D_LOCATION_CLEARED) @@ -849,12 +853,13 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, c = texture->sub_resources[sub_resource_idx].clear_value.colour; }
- wined3d_texture_get_pitch(texture, level_idx, &map.row_pitch, &map.slice_pitch); if (destination.buffer_object) map.data = wined3d_context_map_bo_address(context, &destination, range.size, WINED3D_MAP_WRITE | WINED3D_MAP_DISCARD); else map.data = destination.addr; + map.row_pitch = row_pitch; + map.slice_pitch = slice_pitch;
wined3d_texture_get_level_box(texture, level_idx, &box); wined3d_resource_memory_colour_fill(&texture->resource, &map, &c, &box, true); @@ -865,7 +870,7 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, else { wined3d_texture_get_bo_address(texture, sub_resource_idx, - &source, (current & wined3d_texture_sysmem_locations)); + &source, NULL, NULL, (current & wined3d_texture_sysmem_locations)); wined3d_context_copy_bo_address(context, &destination, &source, 1, &range); } ret = TRUE; @@ -902,13 +907,13 @@ static void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned } if (locations & WINED3D_LOCATION_BUFFER) { - wined3d_texture_get_bo_address(texture, sub_resource_idx, data, WINED3D_LOCATION_BUFFER); + wined3d_texture_get_bo_address(texture, sub_resource_idx, data, NULL, NULL, WINED3D_LOCATION_BUFFER); return; }
if (locations & WINED3D_LOCATION_SYSMEM) { - wined3d_texture_get_bo_address(texture, sub_resource_idx, data, WINED3D_LOCATION_SYSMEM); + wined3d_texture_get_bo_address(texture, sub_resource_idx, data, NULL, NULL, WINED3D_LOCATION_SYSMEM); return; }
@@ -1148,8 +1153,8 @@ static void wined3d_texture_create_dc(void *object) wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding); } 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_bo_address(texture, sub_resource_idx, &data, texture->resource.map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, + &row_pitch, &slice_pitch, texture->resource.map_binding); if (data.buffer_object) { if (!context) @@ -1222,7 +1227,7 @@ static void wined3d_texture_destroy_dc(void *object) dc_info->dc = NULL; dc_info->bitmap = NULL;
- wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, texture->resource.map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, NULL, NULL, texture->resource.map_binding); if (data.buffer_object) { context = context_acquire(device, NULL, 0); @@ -3060,11 +3065,10 @@ 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_bo_address(&texture_gl->t, sub_resource_idx, &data, dst_location); + wined3d_texture_get_bo_address(&texture_gl->t, sub_resource_idx, &data, &row_pitch, &slice_pitch, 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); - wined3d_texture_get_pitch(&texture_gl->t, level, &row_pitch, &slice_pitch); wined3d_texture_gl_download_data(&context_gl->c, &texture_gl->t, sub_resource_idx, src_location, &src_box, &data, texture_gl->t.resource.format, 0, 0, 0, row_pitch, slice_pitch);
@@ -3450,7 +3454,7 @@ static bool wined3d_texture_gl_clear(struct wined3d_texture *texture,
if (!wined3d_texture_prepare_location(texture, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_SYSMEM)) return false; - wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, NULL, NULL, WINED3D_LOCATION_SYSMEM); memset(addr.addr, 0, sub_resource->size); wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); return true; @@ -3774,7 +3778,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour } }
- wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, resource->map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, NULL, NULL, 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); @@ -3824,7 +3828,7 @@ static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *reso
context = context_acquire(device, NULL, 0);
- wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, texture->resource.map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, NULL, NULL, 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); @@ -4671,8 +4675,8 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un 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) { - unsigned int src_level, dst_level, dst_row_pitch, dst_slice_pitch; unsigned int dst_location = dst_texture->resource.map_binding; + unsigned int src_level, dst_row_pitch, dst_slice_pitch; struct wined3d_context *context; struct wined3d_bo_address data; struct wined3d_box src_box; @@ -4681,7 +4685,8 @@ 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_bo_address(dst_texture, dst_sub_resource_idx, &data, dst_location); + wined3d_texture_get_bo_address(dst_texture, dst_sub_resource_idx, + &data, &dst_row_pitch, &dst_slice_pitch, dst_location);
if (src_texture->sub_resources[src_sub_resource_idx].locations & WINED3D_LOCATION_TEXTURE_RGB) src_location = WINED3D_LOCATION_TEXTURE_RGB; @@ -4690,9 +4695,6 @@ void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, src_level = src_sub_resource_idx % src_texture->level_count; wined3d_texture_get_level_box(src_texture, src_level, &src_box);
- dst_level = dst_sub_resource_idx % dst_texture->level_count; - wined3d_texture_get_pitch(dst_texture, dst_level, &dst_row_pitch, &dst_slice_pitch); - src_texture->texture_ops->texture_download_data(context, src_texture, src_sub_resource_idx, src_location, &src_box, &data, dst_texture->resource.format, 0, 0, 0, dst_row_pitch, dst_slice_pitch);
@@ -5335,7 +5337,7 @@ static bool wined3d_texture_vk_clear(struct wined3d_texture_vk *texture_vk,
if (!wined3d_texture_prepare_location(&texture_vk->t, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) return false; - wined3d_texture_get_bo_address(&texture_vk->t, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + wined3d_texture_get_bo_address(&texture_vk->t, sub_resource_idx, &addr, NULL, NULL, WINED3D_LOCATION_SYSMEM); memset(addr.addr, 0, sub_resource->size); wined3d_texture_validate_location(&texture_vk->t, sub_resource_idx, WINED3D_LOCATION_SYSMEM); return true; @@ -5440,9 +5442,8 @@ 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_bo_address(&texture_vk->t, sub_resource_idx, &data, location); + wined3d_texture_get_bo_address(&texture_vk->t, sub_resource_idx, &data, &row_pitch, &slice_pitch, 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, &src_box, &data, texture_vk->t.resource.format, 0, 0, 0, row_pitch, slice_pitch);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f808852ffef..f40949d5256 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4742,8 +4742,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, uint32_t location) DECLSPEC_HIDDEN; +void wined3d_texture_get_bo_address(const struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_bo_address *data, unsigned int *row_pitch, + unsigned int *slice_pitch, uint32_t location) DECLSPEC_HIDDEN; GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_texture_invalidate_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, uint32_t location) DECLSPEC_HIDDEN;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/texture.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 5f639ff4326..41f4e79aebf 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -887,7 +887,8 @@ 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_context *context, struct wined3d_bo_address *data) + struct wined3d_context *context, struct wined3d_bo_address *data, + unsigned int *row_pitch, unsigned int *slice_pitch) { struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx]; DWORD locations = sub_resource->locations; @@ -907,13 +908,15 @@ static void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned } if (locations & WINED3D_LOCATION_BUFFER) { - wined3d_texture_get_bo_address(texture, sub_resource_idx, data, NULL, NULL, WINED3D_LOCATION_BUFFER); + wined3d_texture_get_bo_address(texture, sub_resource_idx, data, + row_pitch, slice_pitch, WINED3D_LOCATION_BUFFER); return; }
if (locations & WINED3D_LOCATION_SYSMEM) { - wined3d_texture_get_bo_address(texture, sub_resource_idx, data, NULL, NULL, WINED3D_LOCATION_SYSMEM); + wined3d_texture_get_bo_address(texture, sub_resource_idx, data, + row_pitch, slice_pitch, WINED3D_LOCATION_SYSMEM); return; }
@@ -3263,8 +3266,6 @@ static BOOL wined3d_texture_gl_load_texture(struct wined3d_texture_gl *texture_g wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_SYSMEM); }
- wined3d_texture_get_pitch(&texture_gl->t, level, &src_row_pitch, &src_slice_pitch); - format = texture_gl->t.resource.format; if ((conversion = wined3d_format_get_color_key_conversion(&texture_gl->t, TRUE))) format = wined3d_get_format(device->adapter, conversion->dst_format, texture_gl->t.resource.bind_flags); @@ -3280,7 +3281,8 @@ 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, &context_gl->c, &data); + wined3d_texture_get_memory(&texture_gl->t, sub_resource_idx, &context_gl->c, + &data, &src_row_pitch, &src_slice_pitch); if (conversion) { width = src_box.right - src_box.left; @@ -4632,9 +4634,9 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un { unsigned int src_row_pitch, src_slice_pitch; unsigned int update_w, update_h, update_d; - unsigned int src_level, dst_level; struct wined3d_context *context; struct wined3d_bo_address data; + unsigned int dst_level;
TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, " "src_texture %p, src_sub_resource_idx %u, src_box %s.\n", @@ -4657,9 +4659,7 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un else 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, context, &data); - wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch); + wined3d_texture_get_memory(src_texture, src_sub_resource_idx, context, &data, &src_row_pitch, &src_slice_pitch);
dst_texture->texture_ops->texture_upload_data(context, wined3d_const_bo_address(&data), src_texture->resource.format, src_box, src_row_pitch, src_slice_pitch, dst_texture, @@ -5416,9 +5416,8 @@ 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, context, &data); + wined3d_texture_get_memory(&texture_vk->t, sub_resource_idx, context, &data, &row_pitch, &slice_pitch); 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, &src_box, row_pitch, slice_pitch, &texture_vk->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB, 0, 0, 0);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/swapchain.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 5638c80b538..eed2fe53d74 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -402,6 +402,7 @@ static void swapchain_blit_gdi(struct wined3d_swapchain *swapchain, D3DKMT_CREATEDCFROMMEMORY create_desc; const struct wined3d_format *format; unsigned int row_pitch, slice_pitch; + struct wined3d_bo_address addr; HDC src_dc, dst_dc; NTSTATUS status; HBITMAP bitmap; @@ -422,9 +423,9 @@ static void swapchain_blit_gdi(struct wined3d_swapchain *swapchain, }
wined3d_texture_load_location(back_buffer, 0, context, WINED3D_LOCATION_SYSMEM); - wined3d_texture_get_pitch(back_buffer, 0, &row_pitch, &slice_pitch); + wined3d_texture_get_bo_address(back_buffer, 0, &addr, &row_pitch, &slice_pitch, WINED3D_LOCATION_SYSMEM);
- create_desc.pMemory = back_buffer->resource.heap_memory; + create_desc.pMemory = addr.addr; create_desc.Format = format->ddi_format; create_desc.Width = wined3d_texture_get_level_width(back_buffer, 0); create_desc.Height = wined3d_texture_get_level_height(back_buffer, 0);
From: Zebediah Figura zfigura@codeweavers.com
Limit it to updating user memory and pitch. --- dlls/d3d9/device.c | 7 +--- dlls/ddraw/surface.c | 14 +++---- dlls/wined3d/texture.c | 81 +++++---------------------------------- dlls/wined3d/wined3d.spec | 2 +- include/wine/wined3d.h | 6 +-- 5 files changed, 19 insertions(+), 91 deletions(-)
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index c6083d351e3..b19d520d620 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1334,9 +1334,7 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, if (set_mem) { wined3d_mutex_lock(); - wined3d_texture_update_desc(object->wined3d_texture, 0, width, height, - wined3dformat_from_d3dformat(format), WINED3D_MULTISAMPLE_NONE, 0, - *shared_handle, 0); + wined3d_texture_update_desc(object->wined3d_texture, 0, *shared_handle, 0); wined3d_mutex_unlock(); }
@@ -1574,8 +1572,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, unsigned i IDirect3DSurface9_AddRef(*surface);
if (user_mem) - wined3d_texture_update_desc(texture, 0, width, height, desc.format, - multisample_type, multisample_quality, user_mem, 0); + wined3d_texture_update_desc(texture, 0, user_mem, 0);
wined3d_texture_decref(texture);
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 52ca900441c..75637e2acf1 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -4812,8 +4812,8 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, { /* Updating memory only. */
- if (FAILED(hr = wined3d_texture_update_desc(surface->wined3d_texture, surface->sub_resource_idx, - width, height, format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch))) + if (FAILED(hr = wined3d_texture_update_desc(surface->wined3d_texture, + surface->sub_resource_idx, DDSD->lpSurface, pitch))) { WARN("Failed to update surface desc, hr %#lx.\n", hr); wined3d_mutex_unlock(); @@ -4856,8 +4856,7 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, return hr_ddraw_from_wined3d(hr); }
- if (FAILED(hr = wined3d_texture_update_desc(new_texture, 0, width, height, - format_id, WINED3D_MULTISAMPLE_NONE, 0, DDSD->lpSurface, pitch))) + if (FAILED(hr = wined3d_texture_update_desc(new_texture, 0, DDSD->lpSurface, pitch))) { ERR("Failed to set user memory, hr %#lx.\n", hr); wined3d_texture_decref(new_texture); @@ -6154,8 +6153,6 @@ static HRESULT ddraw_surface_reserve_memory(struct wined3d_texture *wined3d_text wined3d_texture_get_pitch(wined3d_texture, i, &pitch, &slice_pitch);
if (FAILED(hr = wined3d_texture_update_desc(wined3d_texture, i, - desc.width, desc.height, resource_desc.format, - desc.multisample_type, desc.multisample_quality, (BYTE *)texture->texture_memory + offset, pitch))) { heap_free(texture->texture_memory); @@ -6336,9 +6333,8 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d return hr; }
- if ((desc->dwFlags & DDSD_LPSURFACE) && FAILED(hr = wined3d_texture_update_desc(wined3d_texture, 0, - wined3d_desc.width, wined3d_desc.height, wined3d_desc.format, - WINED3D_MULTISAMPLE_NONE, 0, desc->lpSurface, pitch))) + if ((desc->dwFlags & DDSD_LPSURFACE) + && FAILED(hr = wined3d_texture_update_desc(wined3d_texture, 0, desc->lpSurface, pitch))) { ERR("Failed to set surface memory, hr %#lx.\n", hr); goto fail; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 41f4e79aebf..b2e201a7e55 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1896,54 +1896,34 @@ void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *t checkGLcall("set compatible renderbuffer"); }
-HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, unsigned int sub_resource_idx, - UINT width, UINT height, enum wined3d_format_id format_id, - enum wined3d_multisample_type multisample_type, UINT multisample_quality, void *mem, UINT pitch) +HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, + unsigned int sub_resource_idx, void *mem, unsigned int pitch) { + unsigned int current_row_pitch, current_slice_pitch, width, height; struct wined3d_texture_sub_resource *sub_resource; unsigned int i, level, sub_resource_count; - const struct wined3d_d3d_info *d3d_info; - const struct wined3d_gl_info *gl_info; const struct wined3d_format *format; struct wined3d_device *device; - unsigned int resource_size; unsigned int slice_pitch; bool update_memory_only; bool create_dib = false;
- TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, " - "mem %p, pitch %u, sub_resource_idx %u.\n", - texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_quality, mem, pitch, - sub_resource_idx); + TRACE("texture %p, sub_resource_idx %u, mem %p, pitch %u.\n", texture, sub_resource_idx, mem, pitch);
device = texture->resource.device; - gl_info = &device->adapter->gl_info; - d3d_info = &device->adapter->d3d_info; - format = wined3d_get_format(device->adapter, format_id, texture->resource.bind_flags); - resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1); + format = texture->resource.format; level = sub_resource_idx % texture->level_count; sub_resource_count = texture->level_count * texture->layer_count;
- update_memory_only = width == wined3d_texture_get_level_width(texture, level) - && height == wined3d_texture_get_level_height(texture, level) - && format_id == texture->resource.format->id && multisample_type == texture->resource.multisample_type - && multisample_quality == texture->resource.multisample_quality; - + width = wined3d_texture_get_level_width(texture, level); + height = wined3d_texture_get_level_height(texture, level); if (pitch) slice_pitch = height * pitch; else wined3d_format_calculate_pitch(format, 1, width, height, &pitch, &slice_pitch);
- if (update_memory_only) - { - unsigned int current_row_pitch, current_slice_pitch; - - wined3d_texture_get_pitch(texture, level, ¤t_row_pitch, ¤t_slice_pitch); - update_memory_only = pitch == current_row_pitch && slice_pitch == current_slice_pitch; - } - - if (!resource_size) - return WINED3DERR_INVALIDCALL; + wined3d_texture_get_pitch(texture, level, ¤t_row_pitch, ¤t_slice_pitch); + update_memory_only = (pitch == current_row_pitch && slice_pitch == current_slice_pitch);
if (sub_resource_count > 1 && !update_memory_only) { @@ -2009,60 +1989,17 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, unsig texture->row_pitch = pitch; texture->slice_pitch = slice_pitch;
- texture->resource.format = format; - texture->resource.multisample_type = multisample_type; - texture->resource.multisample_quality = multisample_quality; - texture->resource.width = width; - texture->resource.height = height; if (!(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU) && texture->resource.usage & WINED3DUSAGE_VIDMEM_ACCOUNTING) adapter_adjust_memory(device->adapter, (INT64)texture->slice_pitch - texture->resource.size); texture->resource.size = texture->slice_pitch; sub_resource->size = texture->slice_pitch; sub_resource->locations = WINED3D_LOCATION_DISCARDED; - - if (texture->texture_ops == &texture_gl_ops) - { - if (multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) - { - wined3d_texture_gl(texture)->target = GL_TEXTURE_2D_MULTISAMPLE; - texture->flags &= ~WINED3D_TEXTURE_DOWNLOADABLE; - } - else - { - wined3d_texture_gl(texture)->target = GL_TEXTURE_2D; - texture->flags |= WINED3D_TEXTURE_DOWNLOADABLE; - } - } - - if (((width & (width - 1)) || (height & (height - 1))) && !d3d_info->texture_npot - && !d3d_info->texture_npot_conditional) - { - texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED; - texture->pow2_width = texture->pow2_height = 1; - while (texture->pow2_width < width) - texture->pow2_width <<= 1; - while (texture->pow2_height < height) - texture->pow2_height <<= 1; - } - else - { - texture->flags &= ~WINED3D_TEXTURE_COND_NP2_EMULATED; - texture->pow2_width = width; - texture->pow2_height = height; - } }
if (!mem && !wined3d_resource_prepare_sysmem(&texture->resource)) ERR("Failed to allocate resource memory.\n");
- /* The format might be changed to a format that needs conversion. - * If the surface didn't use PBOs previously but could now, don't - * change it - whatever made us not use PBOs might come back, e.g. - * color keys. */ - if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, d3d_info)) - texture->resource.map_binding = WINED3D_LOCATION_SYSMEM; - wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); wined3d_texture_invalidate_location(texture, sub_resource_idx, ~WINED3D_LOCATION_SYSMEM);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 18035d2cb16..a6ebe2c5081 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -309,7 +309,7 @@ @ cdecl wined3d_texture_set_lod(ptr long) @ cdecl wined3d_texture_set_overlay_position(ptr long long long) @ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr ptr) -@ cdecl wined3d_texture_update_desc(ptr long long long long long long ptr long) +@ cdecl wined3d_texture_update_desc(ptr long ptr long) @ cdecl wined3d_texture_update_overlay(ptr long ptr ptr long ptr long)
@ cdecl wined3d_unordered_access_view_create(ptr ptr ptr ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 32a1a70b040..b400b7003eb 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2870,10 +2870,8 @@ HRESULT __cdecl wined3d_texture_set_overlay_position(struct wined3d_texture *tex unsigned int sub_resource_idx, LONG x, LONG y); void __cdecl wined3d_texture_set_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops); -HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture, unsigned int sub_resource_idx, - UINT width, UINT height, enum wined3d_format_id format_id, - enum wined3d_multisample_type multisample_type, UINT multisample_quality, - void *mem, UINT pitch); +HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture, + unsigned int sub_resource_idx, void *mem, unsigned int pitch); HRESULT __cdecl wined3d_texture_update_overlay(struct wined3d_texture *texture, unsigned int sub_resource_idx, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, uint32_t flags);
v2: fix calculation of sub-resource width and height
Mostly for what it's worth, I don't think there are a lot of good reasons left these days for ddraw accessing the wined3d front buffer. In particular, in ddraw_surface_update_frontbuffer() we should be able to just blit to the back buffer and then call wined3d_swapchain_present() with a 0 swap interval. There are of course some optimisations to wined3d's present path we'd like to make regardless.
We may want to consider building recreate_texture() from patch 3/7 on top of a helper to create a texture from a wined3d_swapchain_desc, shared with wined3d_swapchain_init().
Mostly for what it's worth, I don't think there are a lot of good reasons left these days for ddraw accessing the wined3d front buffer. In particular, in ddraw_surface_update_frontbuffer() we should be able to just blit to the back buffer and then call wined3d_swapchain_present() with a 0 swap interval.
For my own edification, why have we historically rendered directly to the front buffer?
There are of course some optimisations to wined3d's present path we'd like to make regardless.
What do you have in mind?
We may want to consider building recreate_texture() from patch 3/7 on top of a helper to create a texture from a wined3d_swapchain_desc, shared with wined3d_swapchain_init().
Yes, that sounds like a good idea. I'll try adjusting this accordingly.
Mostly for what it's worth, I don't think there are a lot of good reasons left these days for ddraw accessing the wined3d front buffer. In particular, in ddraw_surface_update_frontbuffer() we should be able to just blit to the back buffer and then call wined3d_swapchain_present() with a 0 swap interval.
For my own edification, why have we historically rendered directly to the front buffer?
Originally, because it was the straightforward thing to do; we'd translate ddraw front buffer blits to X11/GL front buffer blits. There was no wined3d at that point, nor necessarily OpenGL. (XFree86-DGA was a thing, once upon a time.)
That model was largely translated as-is when ddraw started using wined3d. There's still a fast-path to implement blits from the back buffer to the front buffer as a call to wined3d_swapchain_present() in texture2d_blt(). Then, at some point ddraw_surface_update_frontbuffer() was introduced. The reasons included fixing issues with drawing outside the swapchain window (if any) when using GL, retaining the contents of swapchain surfaces after Flip(), and fixing some performance issues with applications locking the front buffer by keeping track of the affected rectangle. This effectively virtualised ddraw access to the front buffer, not unlike modern windowing systems tend to do; the performance advantages of directly blitting to the front buffer largely no longer exist today. The introduction of "AlwaysOffscreen" effectively removed direct access to the back buffer.
What remained then was that ddraw_surface_update_frontbuffer() never used wined3d_swapchain_present() until commit 034e88e038e8114ec31261d88dece1e2691185fb. These days it does though, and that pretty much leaves potential overhead of wined3d_swapchain_present() as the only reason for not calling it, perhaps most significantly from swapchain_blit(). I think we should try to reduce that overhead in any case.
There are of course some optimisations to wined3d's present path we'd like to make regardless.
What do you have in mind?
Broadly, I'd like to reduce the number of blits/copies involved in getting surfaces to the screen, and I think we should be able to make some progress on that using an approach similar to wined3d_buffer_set_bo()/UPLOAD_BO_RENAME_ON_UNMAP. I.e., if we're completely replacing the contents of a texture without scaling or format conversion, we could just propagate the underlying texture/VkImage. Ideally we'd be able to do that all the way to the display driver in the kernel.
Mostly for what it's worth, I don't think there are a lot of good reasons left these days for ddraw accessing the wined3d front buffer. In particular, in ddraw_surface_update_frontbuffer() we should be able to just blit to the back buffer and then call wined3d_swapchain_present() with a 0 swap interval.
For my own edification, why have we historically rendered directly to the front buffer?
Originally, because it was the straightforward thing to do; we'd translate ddraw front buffer blits to X11/GL front buffer blits. There was no wined3d at that point, nor necessarily OpenGL. (XFree86-DGA was a thing, once upon a time.)
That model was largely translated as-is when ddraw started using wined3d. There's still a fast-path to implement blits from the back buffer to the front buffer as a call to wined3d_swapchain_present() in texture2d_blt(). Then, at some point ddraw_surface_update_frontbuffer() was introduced. The reasons included fixing issues with drawing outside the swapchain window (if any) when using GL, retaining the contents of swapchain surfaces after Flip(), and fixing some performance issues with applications locking the front buffer by keeping track of the affected rectangle. This effectively virtualised ddraw access to the front buffer, not unlike modern windowing systems tend to do; the performance advantages of directly blitting to the front buffer largely no longer exist today. The introduction of "AlwaysOffscreen" effectively removed direct access to the back buffer.
What remained then was that ddraw_surface_update_frontbuffer() never used wined3d_swapchain_present() until commit 034e88e038e8114ec31261d88dece1e2691185fb. These days it does though, and that pretty much leaves potential overhead of wined3d_swapchain_present() as the only reason for not calling it, perhaps most significantly from swapchain_blit(). I think we should try to reduce that overhead in any case.
Thanks for the explanation, that mostly makes sense.
There are of course some optimisations to wined3d's present path we'd like to make regardless.
What do you have in mind?
Broadly, I'd like to reduce the number of blits/copies involved in getting surfaces to the screen, and I think we should be able to make some progress on that using an approach similar to wined3d_buffer_set_bo()/UPLOAD_BO_RENAME_ON_UNMAP. I.e., if we're completely replacing the contents of a texture without scaling or format conversion, we could just propagate the underlying texture/VkImage. Ideally we'd be able to do that all the way to the display driver in the kernel.
So to make sure I understand... the point here is we can't "just" do that with GL, which is why we want to instead back wined3d swapchains with X11 pixmaps and use XPresent to get them to the screen. Or, in the case of Vulkan, actually back wined3d swapchains with Vulkan swapchains (which we don't currently do yet... why?)
I suppose this will be another case of "that's nice to have, but I don't think it should block this patch". If only because there's too much work I have queued at the moment depending on this...