d3d12: Move logicop descriptor initialization to after all blits

The blit code is destructive on the framebuffer state, which means
that it can set new render targets. If you have 2 BGRA surfaces bound
for logic ops, then after setting up the surface for the first one,
the blit for the second will end up destroying + re-creating the
surface for the first one.

Let's be robust to this by putting the blit in a first pass, and
then actually initializing all of the descriptors in a second pass.

This is still woefully inefficient but at least it's correct.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36945>
This commit is contained in:
Jesse Natalie
2025-08-22 14:31:33 -07:00
committed by Marge Bot
parent cd3885c592
commit fee83f4fcc
3 changed files with 13 additions and 10 deletions

View File

@@ -1160,7 +1160,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
for (int i = 0; i < ctx->fb.nr_cbufs; ++i) {
if (ctx->fb_cbufs[i]) {
struct d3d12_surface *surface = ctx->fb_cbufs[i];
render_targets[i] = d3d12_surface_get_handle(surface, conversion_modes[i]);
render_targets[i] = d3d12_surface_get_handle(surface, conversion_modes[i], d3d12_rtv_format(ctx, i));
d3d12_batch_reference_surface_texture(batch, surface);
} else
render_targets[i] = screen->null_rtv.cpu_handle;

View File

@@ -298,7 +298,6 @@ d3d12_surface_update_pre_draw(struct pipe_context *pctx,
struct d3d12_surface *surface,
DXGI_FORMAT format)
{
struct d3d12_screen *screen = d3d12_screen(pctx->screen);
struct d3d12_resource *res = d3d12_resource(surface->base.texture);
DXGI_FORMAT dxgi_format = d3d12_get_resource_rt_format(surface->base.format);
enum d3d12_surface_conversion_mode mode;
@@ -315,11 +314,6 @@ d3d12_surface_update_pre_draw(struct pipe_context *pctx,
mode = D3D12_SURFACE_CONVERSION_BGRA_UINT;
}
if (!d3d12_descriptor_handle_is_allocated(&surface->uint_rtv_handle)) {
initialize_rtv(screen, res, &surface->base,
&surface->uint_rtv_handle, format);
}
return mode;
}
@@ -334,9 +328,17 @@ d3d12_surface_update_post_draw(struct pipe_context *pctx,
D3D12_CPU_DESCRIPTOR_HANDLE
d3d12_surface_get_handle(struct d3d12_surface *surface,
enum d3d12_surface_conversion_mode mode)
enum d3d12_surface_conversion_mode mode,
DXGI_FORMAT format)
{
if (mode != D3D12_SURFACE_CONVERSION_NONE)
if (mode != D3D12_SURFACE_CONVERSION_NONE) {
struct d3d12_resource *base_res = d3d12_resource(surface->base.texture);
if (!d3d12_descriptor_handle_is_allocated(&surface->uint_rtv_handle)) {
initialize_rtv(surface->screen,
d3d12_resource(d3d12_resource_get_logicop_texture(base_res)),
&surface->base, &surface->uint_rtv_handle, format);
}
return surface->uint_rtv_handle.cpu_handle;
}
return surface->desc_handle.cpu_handle;
}

View File

@@ -55,7 +55,8 @@ d3d12_surface_update_post_draw(struct pipe_context *pctx,
D3D12_CPU_DESCRIPTOR_HANDLE
d3d12_surface_get_handle(struct d3d12_surface *surface,
enum d3d12_surface_conversion_mode mode);
enum d3d12_surface_conversion_mode mode,
DXGI_FORMAT format);
struct d3d12_surface *
d3d12_create_surface(struct d3d12_screen *screen,