From cd3885c59297de7e7567542b08b1c0cf80d5a543 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Fri, 22 Aug 2025 14:22:38 -0700 Subject: [PATCH] d3d12: Move logicop emulation resource from surface to resource Part-of: --- src/gallium/drivers/d3d12/d3d12_draw.cpp | 5 ++- src/gallium/drivers/d3d12/d3d12_resource.cpp | 41 +++++++++++++++++++ src/gallium/drivers/d3d12/d3d12_resource.h | 6 +++ src/gallium/drivers/d3d12/d3d12_surface.cpp | 42 +++++--------------- src/gallium/drivers/d3d12/d3d12_surface.h | 3 +- 5 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index 3ad693c3101..3b1668818df 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -1203,8 +1203,9 @@ d3d12_draw_vbo(struct pipe_context *pctx, if (!surf) continue; - struct pipe_resource *pres = conversion_modes[i] == D3D12_SURFACE_CONVERSION_BGRA_UINT ? - surf->rgba_texture : surf->base.texture; + struct pipe_resource *pres = surf->base.texture; + if (conversion_modes[i] == D3D12_SURFACE_CONVERSION_BGRA_UINT) + pres = d3d12_resource_get_logicop_texture(d3d12_resource(pres)); transition_surface_subresources_state(ctx, &surf->base, pres, D3D12_RESOURCE_STATE_RENDER_TARGET); } diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp b/src/gallium/drivers/d3d12/d3d12_resource.cpp index 5f5b585d010..eda22c25346 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource.cpp +++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp @@ -93,6 +93,8 @@ d3d12_resource_destroy(struct pipe_screen *pscreen, util_range_destroy(&resource->valid_buffer_range); if (resource->bo) d3d12_bo_unreference(resource->bo); + if (resource->logicop_texture) + pipe_resource_reference(&resource->logicop_texture, NULL); FREE(resource); } @@ -2029,3 +2031,42 @@ d3d12_context_resource_init(struct pipe_context *pctx) pctx->buffer_subdata = u_default_buffer_subdata; pctx->texture_subdata = u_default_texture_subdata; } + +static void +d3d12_resource_init_logicop_texture(const void *data) +{ + struct d3d12_resource *res = (struct d3d12_resource *)data; + struct pipe_resource templ = {}; + struct pipe_resource *src = &res->base.b; + + templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; + templ.width0 = src->width0; + templ.height0 = src->height0; + templ.depth0 = src->depth0; + templ.array_size = src->array_size; + templ.nr_samples = src->nr_samples; + templ.nr_storage_samples = src->nr_storage_samples; + templ.usage = PIPE_USAGE_STAGING; + templ.bind = src->bind; + templ.target = src->target; + + res->logicop_texture = src->screen->resource_create(src->screen, &templ); +} + +struct pipe_resource * +d3d12_resource_get_logicop_texture(struct d3d12_resource *res) +{ + switch (res->dxgi_format) { + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + break; + default: + return &res->base.b; + } + util_call_once_data(&res->logicop_texture_init_flag, d3d12_resource_init_logicop_texture, res); + return res->logicop_texture; +} diff --git a/src/gallium/drivers/d3d12/d3d12_resource.h b/src/gallium/drivers/d3d12/d3d12_resource.h index 2c41fa9ff71..fc679ff4a6a 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource.h +++ b/src/gallium/drivers/d3d12/d3d12_resource.h @@ -57,6 +57,9 @@ struct d3d12_resource { struct util_range valid_buffer_range; uint32_t bind_counts[MESA_SHADER_STAGES][D3D12_RESOURCE_BINDING_TYPES]; unsigned generation_id; + + util_once_flag logicop_texture_init_flag; + struct pipe_resource *logicop_texture; }; struct d3d12_memory_object { @@ -140,4 +143,7 @@ struct pipe_resource * d3d12_resource_from_resource(struct pipe_screen *pscreen, ID3D12Resource* inputRes); +struct pipe_resource * +d3d12_resource_get_logicop_texture(struct d3d12_resource *res); + #endif diff --git a/src/gallium/drivers/d3d12/d3d12_surface.cpp b/src/gallium/drivers/d3d12/d3d12_surface.cpp index 2ad65a80b1c..e8b7912ec2c 100644 --- a/src/gallium/drivers/d3d12/d3d12_surface.cpp +++ b/src/gallium/drivers/d3d12/d3d12_surface.cpp @@ -268,17 +268,17 @@ d3d12_surface_destroy(struct d3d12_surface *surface) mtx_unlock(&screen->descriptor_pool_mutex); pipe_resource_reference(&surface->base.texture, NULL); - pipe_resource_reference(&surface->rgba_texture, NULL); FREE(surface); } static void -blit_surface(struct pipe_context *pctx, struct d3d12_surface *surface, bool pre) +blit_logicop_surface(struct pipe_context *pctx, struct d3d12_surface *surface, bool pre) { struct pipe_blit_info info = {}; + struct pipe_resource *logicop_surface = d3d12_resource_get_logicop_texture(d3d12_resource(surface->base.texture)); - info.src.resource = pre ? surface->base.texture : surface->rgba_texture; - info.dst.resource = pre ? surface->rgba_texture : surface->base.texture; + info.src.resource = pre ? surface->base.texture : logicop_surface; + info.dst.resource = pre ? logicop_surface : surface->base.texture; info.src.format = pre ? surface->base.texture->format : PIPE_FORMAT_R8G8B8A8_UNORM; info.dst.format = pre ? PIPE_FORMAT_R8G8B8A8_UNORM : surface->base.texture->format; info.src.level = info.dst.level = 0; @@ -306,33 +306,13 @@ d3d12_surface_update_pre_draw(struct pipe_context *pctx, if (dxgi_format == format) return D3D12_SURFACE_CONVERSION_NONE; - if (dxgi_format == DXGI_FORMAT_B8G8R8A8_UNORM || - dxgi_format == DXGI_FORMAT_B8G8R8X8_UNORM) - mode = D3D12_SURFACE_CONVERSION_BGRA_UINT; - else + struct pipe_resource *logicop_resource = d3d12_resource_get_logicop_texture(res); + if (logicop_resource == surface->base.texture) { mode = D3D12_SURFACE_CONVERSION_RGBA_UINT; - - if (mode == D3D12_SURFACE_CONVERSION_BGRA_UINT) { - if (!surface->rgba_texture) { - struct pipe_resource templ = {}; - struct pipe_resource *src = surface->base.texture; - - templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; - templ.width0 = src->width0; - templ.height0 = src->height0; - templ.depth0 = src->depth0; - templ.array_size = src->array_size; - templ.nr_samples = src->nr_samples; - templ.nr_storage_samples = src->nr_storage_samples; - templ.usage = PIPE_USAGE_STAGING; - templ.bind = src->bind; - templ.target = src->target; - - surface->rgba_texture = screen->base.resource_create(&screen->base, &templ); - } - - blit_surface(pctx, surface, true); - res = d3d12_resource(surface->rgba_texture); + } else { + blit_logicop_surface(pctx, surface, true); + res = d3d12_resource(logicop_resource); + mode = D3D12_SURFACE_CONVERSION_BGRA_UINT; } if (!d3d12_descriptor_handle_is_allocated(&surface->uint_rtv_handle)) { @@ -349,7 +329,7 @@ d3d12_surface_update_post_draw(struct pipe_context *pctx, enum d3d12_surface_conversion_mode mode) { if (mode == D3D12_SURFACE_CONVERSION_BGRA_UINT) - blit_surface(pctx, surface, false); + blit_logicop_surface(pctx, surface, false); } D3D12_CPU_DESCRIPTOR_HANDLE diff --git a/src/gallium/drivers/d3d12/d3d12_surface.h b/src/gallium/drivers/d3d12/d3d12_surface.h index b9885bad976..853914b79ad 100644 --- a/src/gallium/drivers/d3d12/d3d12_surface.h +++ b/src/gallium/drivers/d3d12/d3d12_surface.h @@ -32,9 +32,8 @@ struct pipe_context; struct d3d12_surface { struct pipe_surface base; struct d3d12_screen *screen; - struct d3d12_descriptor_handle uint_rtv_handle; - struct pipe_resource *rgba_texture; + struct d3d12_descriptor_handle uint_rtv_handle; struct d3d12_descriptor_handle desc_handle; };