diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index 639f3b77cd1..113edf06a8b 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -207,7 +207,8 @@ struct d3d12_context { struct hash_table *compute_transform_cache; struct pipe_constant_buffer cbufs[MESA_SHADER_STAGES][PIPE_MAX_CONSTANT_BUFFERS]; - PIPE_FB_SURFACES; //STOP USING THIS + struct d3d12_surface *fb_cbufs[PIPE_MAX_COLOR_BUFS]; + struct d3d12_surface *fb_zsbuf; struct pipe_framebuffer_state fb; struct pipe_vertex_buffer vbs[PIPE_MAX_ATTRIBS]; D3D12_VERTEX_BUFFER_VIEW vbvs[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/drivers/d3d12/d3d12_context_common.cpp b/src/gallium/drivers/d3d12/d3d12_context_common.cpp index 13a06ceeace..fdc283485fd 100644 --- a/src/gallium/drivers/d3d12/d3d12_context_common.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context_common.cpp @@ -104,7 +104,6 @@ d3d12_context_destroy(struct pipe_context *pctx) if (ctx->timestamp_query) pctx->destroy_query(pctx, ctx->timestamp_query); - util_framebuffer_init(pctx, NULL, ctx->fb_cbufs, &ctx->fb_zsbuf); util_unreference_framebuffer_state(&ctx->fb); d3d12_compute_pipeline_state_cache_destroy(ctx); d3d12_root_signature_cache_destroy(ctx); @@ -435,7 +434,6 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->gfx_pipeline_state.sample_mask = ~0; - d3d12_context_surface_init(&ctx->base); d3d12_context_query_init(&ctx->base); ctx->queries_disabled = false; diff --git a/src/gallium/drivers/d3d12/d3d12_context_graphics.cpp b/src/gallium/drivers/d3d12/d3d12_context_graphics.cpp index 5334ca3d62d..64ee89f9383 100644 --- a/src/gallium/drivers/d3d12/d3d12_context_graphics.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context_graphics.cpp @@ -1409,6 +1409,47 @@ d3d12_set_constant_buffer(struct pipe_context *pctx, ctx->shader_dirty[shader] |= D3D12_SHADER_DIRTY_CONSTBUF; } +static void +d3d12_framebuffer_init(struct d3d12_context *ctx, const struct pipe_framebuffer_state *fb) +{ + struct d3d12_screen *screen = d3d12_screen(ctx->base.screen); + + if (fb) { + for (unsigned i = 0; i < fb->nr_cbufs; i++) { + if (ctx->fb_cbufs[i] && pipe_surface_equal(&fb->cbufs[i], &ctx->fb_cbufs[i]->base)) + continue; + + struct d3d12_surface *surf = fb->cbufs[i].texture ? + d3d12_create_surface(screen, &fb->cbufs[i]) : + NULL; + if (ctx->fb_cbufs[i]) + d3d12_surface_reference(&ctx->fb_cbufs[i], NULL); + ctx->fb_cbufs[i] = surf; + } + + for (unsigned i = fb->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) { + if (ctx->fb_cbufs[i]) + d3d12_surface_reference(&ctx->fb_cbufs[i], NULL); + } + + if (ctx->fb_zsbuf && pipe_surface_equal(&fb->zsbuf, &ctx->fb_zsbuf->base)) + return; + struct d3d12_surface *zsurf = fb->zsbuf.texture ? + d3d12_create_surface(screen, &fb->zsbuf) : + NULL; + if (ctx->fb_zsbuf) + d3d12_surface_reference(&ctx->fb_zsbuf, NULL); + ctx->fb_zsbuf = zsurf; + } else { + for (unsigned i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + if (ctx->fb_cbufs[i]) + d3d12_surface_reference(&ctx->fb_cbufs[i], NULL); + } + if (ctx->fb_zsbuf) + d3d12_surface_reference(&ctx->fb_zsbuf, NULL); + } +} + static void d3d12_set_framebuffer_state(struct pipe_context *pctx, const struct pipe_framebuffer_state *state) @@ -1417,7 +1458,7 @@ d3d12_set_framebuffer_state(struct pipe_context *pctx, int samples = -1; bool prev_cbufs_or_zsbuf = ctx->fb.nr_cbufs || ctx->fb.zsbuf.texture; - util_framebuffer_init(pctx, state, ctx->fb_cbufs, &ctx->fb_zsbuf); + d3d12_framebuffer_init(ctx, state); util_copy_framebuffer_state(&d3d12_context(pctx)->fb, state); bool new_cbufs_or_zsbuf = ctx->fb.nr_cbufs || ctx->fb.zsbuf.texture; @@ -1979,8 +2020,7 @@ d3d12_clear_render_target(struct pipe_context *pctx, } util_blitter_clear_render_target(ctx->blitter, psurf, &local_color, dstx, dsty, width, height); } else { - struct pipe_surface *tmpsurf = pctx->create_surface(pctx, psurf->texture, psurf); - struct d3d12_surface *surf = d3d12_surface(tmpsurf); + struct d3d12_surface *surf = d3d12_create_surface(d3d12_screen(pctx->screen), psurf); if (!(util_format_colormask(util_format_description(psurf->format)) & PIPE_MASK_A)) @@ -1993,7 +2033,7 @@ d3d12_clear_render_target(struct pipe_context *pctx, clear_color, 1, &rect); ctx->has_commands = true; d3d12_batch_reference_surface_texture(d3d12_current_batch(ctx), surf); - pipe_surface_unref(pctx, &tmpsurf); + d3d12_surface_destroy(surf); } @@ -2013,8 +2053,7 @@ d3d12_clear_depth_stencil(struct pipe_context *pctx, bool render_condition_enabled) { struct d3d12_context *ctx = d3d12_context(pctx); - struct pipe_surface *tmpsurf = pctx->create_surface(pctx, psurf->texture, psurf); - struct d3d12_surface *surf = d3d12_surface(tmpsurf); + struct d3d12_surface *surf = d3d12_create_surface(d3d12_screen(pctx->screen), psurf); if (!render_condition_enabled && ctx->current_predication) ctx->cmdlist->SetPredication(NULL, 0, D3D12_PREDICATION_OP_EQUAL_ZERO); @@ -2043,7 +2082,7 @@ d3d12_clear_depth_stencil(struct pipe_context *pctx, if (!render_condition_enabled && ctx->current_predication) { d3d12_enable_predication(ctx); } - pipe_surface_unref(pctx, &tmpsurf); + d3d12_surface_destroy(surf); } static void diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index 73de1871268..3ad693c3101 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -940,7 +940,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 = d3d12_surface(ctx->fb_cbufs[i]); + struct d3d12_surface *surface = ctx->fb_cbufs[i]; conversion_modes[i] = d3d12_surface_update_pre_draw(pctx, surface, d3d12_rtv_format(ctx, i)); if (conversion_modes[i] != D3D12_SURFACE_CONVERSION_NONE) ctx->cmdlist_dirty |= D3D12_DIRTY_FRAMEBUFFER; @@ -1159,14 +1159,14 @@ d3d12_draw_vbo(struct pipe_context *pctx, D3D12_CPU_DESCRIPTOR_HANDLE *depth_desc = NULL, tmp_desc; for (int i = 0; i < ctx->fb.nr_cbufs; ++i) { if (ctx->fb_cbufs[i]) { - struct d3d12_surface *surface = d3d12_surface(ctx->fb_cbufs[i]); + struct d3d12_surface *surface = ctx->fb_cbufs[i]; render_targets[i] = d3d12_surface_get_handle(surface, conversion_modes[i]); d3d12_batch_reference_surface_texture(batch, surface); } else render_targets[i] = screen->null_rtv.cpu_handle; } if (ctx->fb_zsbuf) { - struct d3d12_surface *surface = d3d12_surface(ctx->fb_zsbuf); + struct d3d12_surface *surface = ctx->fb_zsbuf; tmp_desc = surface->desc_handle.cpu_handle; d3d12_batch_reference_surface_texture(batch, surface); depth_desc = &tmp_desc; @@ -1199,18 +1199,18 @@ d3d12_draw_vbo(struct pipe_context *pctx, ctx->cmdlist->SOSetTargets(0, 4, so_buffer_views); for (int i = 0; i < ctx->fb.nr_cbufs; ++i) { - struct pipe_surface *psurf = ctx->fb_cbufs[i]; - if (!psurf) + struct d3d12_surface *surf = ctx->fb_cbufs[i]; + if (!surf) continue; struct pipe_resource *pres = conversion_modes[i] == D3D12_SURFACE_CONVERSION_BGRA_UINT ? - d3d12_surface(psurf)->rgba_texture : psurf->texture; - transition_surface_subresources_state(ctx, psurf, pres, + surf->rgba_texture : surf->base.texture; + transition_surface_subresources_state(ctx, &surf->base, pres, D3D12_RESOURCE_STATE_RENDER_TARGET); } if (ctx->fb_zsbuf) { - struct pipe_surface *psurf = ctx->fb_zsbuf; - transition_surface_subresources_state(ctx, psurf, psurf->texture, + struct d3d12_surface *surf = ctx->fb_zsbuf; + transition_surface_subresources_state(ctx, &surf->base, surf->base.texture, D3D12_RESOURCE_STATE_DEPTH_WRITE); } @@ -1274,7 +1274,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 = d3d12_surface(ctx->fb_cbufs[i]); + struct d3d12_surface *surface = ctx->fb_cbufs[i]; d3d12_surface_update_post_draw(pctx, surface, conversion_modes[i]); } } diff --git a/src/gallium/drivers/d3d12/d3d12_surface.cpp b/src/gallium/drivers/d3d12/d3d12_surface.cpp index 5e0a83d9d4a..2ad65a80b1c 100644 --- a/src/gallium/drivers/d3d12/d3d12_surface.cpp +++ b/src/gallium/drivers/d3d12/d3d12_surface.cpp @@ -81,20 +81,17 @@ view_rtv_dimension(enum pipe_texture_target target, unsigned samples) } static void -initialize_dsv(struct pipe_context *pctx, - struct pipe_resource *pres, +initialize_dsv(struct d3d12_screen *screen, + struct d3d12_resource *res, const struct pipe_surface *tpl, struct d3d12_descriptor_handle *handle, DXGI_FORMAT dxgi_format) { - struct d3d12_resource *res = d3d12_resource(pres); - struct d3d12_screen *screen = d3d12_screen(pctx->screen); - D3D12_DEPTH_STENCIL_VIEW_DESC desc; desc.Format = dxgi_format; desc.Flags = D3D12_DSV_FLAG_NONE; - desc.ViewDimension = view_dsv_dimension(pres->target, pres->nr_samples); + desc.ViewDimension = view_dsv_dimension(res->base.b.target, res->base.b.nr_samples); switch (desc.ViewDimension) { case D3D12_DSV_DIMENSION_TEXTURE1D: if (tpl->first_layer > 0) @@ -149,23 +146,21 @@ initialize_dsv(struct pipe_context *pctx, } static void -initialize_rtv(struct pipe_context *pctx, - struct pipe_resource *pres, +initialize_rtv(struct d3d12_screen *screen, + struct d3d12_resource *res, const struct pipe_surface *tpl, struct d3d12_descriptor_handle *handle, DXGI_FORMAT dxgi_format) { - struct d3d12_resource *res = d3d12_resource(pres); - struct d3d12_screen *screen = d3d12_screen(pctx->screen); D3D12_RENDER_TARGET_VIEW_DESC desc; desc.Format = dxgi_format; - desc.ViewDimension = view_rtv_dimension(pres->target, pres->nr_samples); + desc.ViewDimension = view_rtv_dimension(res->base.b.target, res->base.b.nr_samples); switch (desc.ViewDimension) { case D3D12_RTV_DIMENSION_BUFFER: desc.Buffer.FirstElement = 0; - desc.Buffer.NumElements = pres->width0 / util_format_get_blocksize(tpl->format); + desc.Buffer.NumElements = res->base.b.width0 / util_format_get_blocksize(tpl->format); break; case D3D12_RTV_DIMENSION_TEXTURE1D: @@ -227,26 +222,26 @@ initialize_rtv(struct pipe_context *pctx, handle->cpu_handle); } -static struct pipe_surface * -d3d12_create_surface(struct pipe_context *pctx, - struct pipe_resource *pres, +struct d3d12_surface * +d3d12_create_surface(struct d3d12_screen *screen, const struct pipe_surface *tpl) { + struct d3d12_resource *res = d3d12_resource(tpl->texture); bool is_depth_or_stencil = util_format_is_depth_or_stencil(tpl->format); unsigned bind = is_depth_or_stencil ? PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET; /* Don't bother if we don't support the requested format as RT or DS */ - if (!pctx->screen->is_format_supported(pctx->screen, tpl->format, PIPE_TEXTURE_2D, - tpl->nr_samples, tpl->nr_samples,bind)) + if (!screen->base.is_format_supported(&screen->base, tpl->format, PIPE_TEXTURE_2D, + tpl->nr_samples, tpl->nr_samples,bind)) return NULL; struct d3d12_surface *surface = CALLOC_STRUCT(d3d12_surface); if (!surface) return NULL; - pipe_resource_reference(&surface->base.texture, pres); + pipe_resource_reference(&surface->base.texture, &res->base.b); pipe_reference_init(&surface->base.reference, 1); - surface->base.context = pctx; + surface->screen = screen; surface->base.format = tpl->format; surface->base.level = tpl->level; surface->base.first_layer = tpl->first_layer; @@ -254,19 +249,17 @@ d3d12_create_surface(struct pipe_context *pctx, DXGI_FORMAT dxgi_format = d3d12_get_resource_rt_format(tpl->format); if (is_depth_or_stencil) - initialize_dsv(pctx, pres, tpl, &surface->desc_handle, dxgi_format); + initialize_dsv(screen, res, tpl, &surface->desc_handle, dxgi_format); else - initialize_rtv(pctx, pres, tpl, &surface->desc_handle, dxgi_format); + initialize_rtv(screen, res, tpl, &surface->desc_handle, dxgi_format); - return &surface->base; + return surface; } -static void -d3d12_surface_destroy(struct pipe_context *pctx, - struct pipe_surface *psurf) +void +d3d12_surface_destroy(struct d3d12_surface *surface) { - struct d3d12_surface *surface = (struct d3d12_surface*) psurf; - struct d3d12_screen *screen = d3d12_screen(pctx->screen); + struct d3d12_screen *screen = surface->screen; mtx_lock(&screen->descriptor_pool_mutex); d3d12_descriptor_handle_free(&surface->desc_handle); @@ -274,7 +267,7 @@ d3d12_surface_destroy(struct pipe_context *pctx, d3d12_descriptor_handle_free(&surface->uint_rtv_handle); mtx_unlock(&screen->descriptor_pool_mutex); - pipe_resource_reference(&psurf->texture, NULL); + pipe_resource_reference(&surface->base.texture, NULL); pipe_resource_reference(&surface->rgba_texture, NULL); FREE(surface); } @@ -343,8 +336,8 @@ d3d12_surface_update_pre_draw(struct pipe_context *pctx, } if (!d3d12_descriptor_handle_is_allocated(&surface->uint_rtv_handle)) { - initialize_rtv(pctx, &res->base.b, &surface->base, - &surface->uint_rtv_handle, DXGI_FORMAT_R8G8B8A8_UINT); + initialize_rtv(screen, res, &surface->base, + &surface->uint_rtv_handle, format); } return mode; @@ -367,10 +360,3 @@ d3d12_surface_get_handle(struct d3d12_surface *surface, return surface->uint_rtv_handle.cpu_handle; return surface->desc_handle.cpu_handle; } - -void -d3d12_context_surface_init(struct pipe_context *context) -{ - context->create_surface = d3d12_create_surface; - context->surface_destroy = d3d12_surface_destroy; -} diff --git a/src/gallium/drivers/d3d12/d3d12_surface.h b/src/gallium/drivers/d3d12/d3d12_surface.h index e8f26889152..b9885bad976 100644 --- a/src/gallium/drivers/d3d12/d3d12_surface.h +++ b/src/gallium/drivers/d3d12/d3d12_surface.h @@ -31,6 +31,7 @@ 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; @@ -43,12 +44,6 @@ enum d3d12_surface_conversion_mode { D3D12_SURFACE_CONVERSION_BGRA_UINT, }; -static inline struct d3d12_surface * -d3d12_surface(struct pipe_surface *psurf) -{ - return (struct d3d12_surface *)psurf; -} - enum d3d12_surface_conversion_mode d3d12_surface_update_pre_draw(struct pipe_context *pctx, struct d3d12_surface *surface, @@ -63,7 +58,24 @@ D3D12_CPU_DESCRIPTOR_HANDLE d3d12_surface_get_handle(struct d3d12_surface *surface, enum d3d12_surface_conversion_mode mode); +struct d3d12_surface * +d3d12_create_surface(struct d3d12_screen *screen, + const struct pipe_surface *tpl); + void -d3d12_context_surface_init(struct pipe_context *context); +d3d12_surface_destroy(struct d3d12_surface *surf); + +static inline void +d3d12_surface_reference(struct d3d12_surface **dst, struct d3d12_surface *src) +{ + struct d3d12_surface *old_dst = *dst; + + if (pipe_reference_described(old_dst ? &old_dst->base.reference : NULL, + src ? &src->base.reference : NULL, + (debug_reference_descriptor) + debug_describe_surface)) + d3d12_surface_destroy(old_dst); + *dst = src; +} #endif