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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user