d3d12: Move logicop emulation resource from surface to resource

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36945>
This commit is contained in:
Jesse Natalie 2025-08-22 14:22:38 -07:00 committed by Marge Bot
parent 784f93653a
commit cd3885c592
5 changed files with 62 additions and 35 deletions

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;
};