1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "d3d12_context.h" 25bf215546Sopenharmony_ci#include "d3d12_format.h" 26bf215546Sopenharmony_ci#include "d3d12_resource.h" 27bf215546Sopenharmony_ci#include "d3d12_screen.h" 28bf215546Sopenharmony_ci#include "d3d12_surface.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "util/format/u_format.h" 31bf215546Sopenharmony_ci#include "util/u_inlines.h" 32bf215546Sopenharmony_ci#include "util/u_memory.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cistatic D3D12_DSV_DIMENSION 35bf215546Sopenharmony_ciview_dsv_dimension(enum pipe_texture_target target, unsigned samples) 36bf215546Sopenharmony_ci{ 37bf215546Sopenharmony_ci switch (target) { 38bf215546Sopenharmony_ci case PIPE_TEXTURE_1D: return D3D12_DSV_DIMENSION_TEXTURE1D; 39bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: return D3D12_DSV_DIMENSION_TEXTURE1DARRAY; 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 42bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 43bf215546Sopenharmony_ci return samples > 1 ? D3D12_DSV_DIMENSION_TEXTURE2DMS : 44bf215546Sopenharmony_ci D3D12_DSV_DIMENSION_TEXTURE2D; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 47bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 48bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 49bf215546Sopenharmony_ci return samples > 1 ? D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY : 50bf215546Sopenharmony_ci D3D12_DSV_DIMENSION_TEXTURE2DARRAY; 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci default: 53bf215546Sopenharmony_ci unreachable("unexpected target"); 54bf215546Sopenharmony_ci } 55bf215546Sopenharmony_ci} 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_cistatic D3D12_RTV_DIMENSION 58bf215546Sopenharmony_ciview_rtv_dimension(enum pipe_texture_target target, unsigned samples) 59bf215546Sopenharmony_ci{ 60bf215546Sopenharmony_ci switch (target) { 61bf215546Sopenharmony_ci case PIPE_BUFFER: return D3D12_RTV_DIMENSION_BUFFER; 62bf215546Sopenharmony_ci case PIPE_TEXTURE_1D: return D3D12_RTV_DIMENSION_TEXTURE1D; 63bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: return D3D12_RTV_DIMENSION_TEXTURE1DARRAY; 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 66bf215546Sopenharmony_ci case PIPE_TEXTURE_RECT: 67bf215546Sopenharmony_ci return samples > 1 ? D3D12_RTV_DIMENSION_TEXTURE2DMS : 68bf215546Sopenharmony_ci D3D12_RTV_DIMENSION_TEXTURE2D; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 71bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE: 72bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 73bf215546Sopenharmony_ci return samples > 1 ? D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY : 74bf215546Sopenharmony_ci D3D12_RTV_DIMENSION_TEXTURE2DARRAY; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: return D3D12_RTV_DIMENSION_TEXTURE3D; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci default: 79bf215546Sopenharmony_ci unreachable("unexpected target"); 80bf215546Sopenharmony_ci } 81bf215546Sopenharmony_ci} 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_cistatic void 84bf215546Sopenharmony_ciinitialize_dsv(struct pipe_context *pctx, 85bf215546Sopenharmony_ci struct pipe_resource *pres, 86bf215546Sopenharmony_ci const struct pipe_surface *tpl, 87bf215546Sopenharmony_ci struct d3d12_descriptor_handle *handle, 88bf215546Sopenharmony_ci DXGI_FORMAT dxgi_format) 89bf215546Sopenharmony_ci{ 90bf215546Sopenharmony_ci struct d3d12_resource *res = d3d12_resource(pres); 91bf215546Sopenharmony_ci struct d3d12_screen *screen = d3d12_screen(pctx->screen); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci D3D12_DEPTH_STENCIL_VIEW_DESC desc; 94bf215546Sopenharmony_ci desc.Format = dxgi_format; 95bf215546Sopenharmony_ci desc.Flags = D3D12_DSV_FLAG_NONE; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci desc.ViewDimension = view_dsv_dimension(pres->target, pres->nr_samples); 98bf215546Sopenharmony_ci switch (desc.ViewDimension) { 99bf215546Sopenharmony_ci case D3D12_DSV_DIMENSION_TEXTURE1D: 100bf215546Sopenharmony_ci if (tpl->u.tex.first_layer > 0) 101bf215546Sopenharmony_ci debug_printf("D3D12: can't create 1D DSV from layer %d\n", 102bf215546Sopenharmony_ci tpl->u.tex.first_layer); 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci desc.Texture1D.MipSlice = tpl->u.tex.level; 105bf215546Sopenharmony_ci break; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci case D3D12_DSV_DIMENSION_TEXTURE1DARRAY: 108bf215546Sopenharmony_ci desc.Texture1DArray.MipSlice = tpl->u.tex.level; 109bf215546Sopenharmony_ci desc.Texture1DArray.FirstArraySlice = tpl->u.tex.first_layer; 110bf215546Sopenharmony_ci desc.Texture1DArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1; 111bf215546Sopenharmony_ci break; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci case D3D12_DSV_DIMENSION_TEXTURE2DMS: 114bf215546Sopenharmony_ci if (tpl->u.tex.first_layer > 0) 115bf215546Sopenharmony_ci debug_printf("D3D12: can't create 2DMS DSV from layer %d\n", 116bf215546Sopenharmony_ci tpl->u.tex.first_layer); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci break; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci case D3D12_DSV_DIMENSION_TEXTURE2D: 121bf215546Sopenharmony_ci if (tpl->u.tex.first_layer > 0) 122bf215546Sopenharmony_ci debug_printf("D3D12: can't create 2D DSV from layer %d\n", 123bf215546Sopenharmony_ci tpl->u.tex.first_layer); 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci desc.Texture2D.MipSlice = tpl->u.tex.level; 126bf215546Sopenharmony_ci break; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY: 129bf215546Sopenharmony_ci desc.Texture2DMSArray.FirstArraySlice = tpl->u.tex.first_layer; 130bf215546Sopenharmony_ci desc.Texture2DMSArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1; 131bf215546Sopenharmony_ci break; 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: 134bf215546Sopenharmony_ci desc.Texture2DArray.MipSlice = tpl->u.tex.level; 135bf215546Sopenharmony_ci desc.Texture2DArray.FirstArraySlice = tpl->u.tex.first_layer; 136bf215546Sopenharmony_ci desc.Texture2DArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1; 137bf215546Sopenharmony_ci break; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci default: 140bf215546Sopenharmony_ci unreachable("Unhandled DSV dimension"); 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci mtx_lock(&screen->descriptor_pool_mutex); 144bf215546Sopenharmony_ci d3d12_descriptor_pool_alloc_handle(screen->dsv_pool, handle); 145bf215546Sopenharmony_ci mtx_unlock(&screen->descriptor_pool_mutex); 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci screen->dev->CreateDepthStencilView(d3d12_resource_resource(res), &desc, 148bf215546Sopenharmony_ci handle->cpu_handle); 149bf215546Sopenharmony_ci} 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_cistatic void 152bf215546Sopenharmony_ciinitialize_rtv(struct pipe_context *pctx, 153bf215546Sopenharmony_ci struct pipe_resource *pres, 154bf215546Sopenharmony_ci const struct pipe_surface *tpl, 155bf215546Sopenharmony_ci struct d3d12_descriptor_handle *handle, 156bf215546Sopenharmony_ci DXGI_FORMAT dxgi_format) 157bf215546Sopenharmony_ci{ 158bf215546Sopenharmony_ci struct d3d12_resource *res = d3d12_resource(pres); 159bf215546Sopenharmony_ci struct d3d12_screen *screen = d3d12_screen(pctx->screen); 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci D3D12_RENDER_TARGET_VIEW_DESC desc; 162bf215546Sopenharmony_ci desc.Format = dxgi_format; 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci desc.ViewDimension = view_rtv_dimension(pres->target, pres->nr_samples); 165bf215546Sopenharmony_ci switch (desc.ViewDimension) { 166bf215546Sopenharmony_ci case D3D12_RTV_DIMENSION_BUFFER: 167bf215546Sopenharmony_ci desc.Buffer.FirstElement = 0; 168bf215546Sopenharmony_ci desc.Buffer.NumElements = pres->width0 / util_format_get_blocksize(tpl->format); 169bf215546Sopenharmony_ci break; 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci case D3D12_RTV_DIMENSION_TEXTURE1D: 172bf215546Sopenharmony_ci if (tpl->u.tex.first_layer > 0) 173bf215546Sopenharmony_ci debug_printf("D3D12: can't create 1D RTV from layer %d\n", 174bf215546Sopenharmony_ci tpl->u.tex.first_layer); 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci desc.Texture1D.MipSlice = tpl->u.tex.level; 177bf215546Sopenharmony_ci break; 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci case D3D12_RTV_DIMENSION_TEXTURE1DARRAY: 180bf215546Sopenharmony_ci desc.Texture1DArray.MipSlice = tpl->u.tex.level; 181bf215546Sopenharmony_ci desc.Texture1DArray.FirstArraySlice = tpl->u.tex.first_layer; 182bf215546Sopenharmony_ci desc.Texture1DArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1; 183bf215546Sopenharmony_ci break; 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci case D3D12_RTV_DIMENSION_TEXTURE2DMS: 186bf215546Sopenharmony_ci if (tpl->u.tex.first_layer > 0) 187bf215546Sopenharmony_ci debug_printf("D3D12: can't create 2DMS RTV from layer %d\n", 188bf215546Sopenharmony_ci tpl->u.tex.first_layer); 189bf215546Sopenharmony_ci break; 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci case D3D12_RTV_DIMENSION_TEXTURE2D: 192bf215546Sopenharmony_ci if (tpl->u.tex.first_layer > 0) 193bf215546Sopenharmony_ci debug_printf("D3D12: can't create 2D RTV from layer %d\n", 194bf215546Sopenharmony_ci tpl->u.tex.first_layer); 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci desc.Texture2D.MipSlice = tpl->u.tex.level; 197bf215546Sopenharmony_ci desc.Texture2D.PlaneSlice = res->plane_slice; 198bf215546Sopenharmony_ci break; 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci case D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY: 201bf215546Sopenharmony_ci desc.Texture2DMSArray.FirstArraySlice = tpl->u.tex.first_layer; 202bf215546Sopenharmony_ci desc.Texture2DMSArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1; 203bf215546Sopenharmony_ci break; 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: 206bf215546Sopenharmony_ci desc.Texture2DArray.MipSlice = tpl->u.tex.level; 207bf215546Sopenharmony_ci desc.Texture2DArray.FirstArraySlice = tpl->u.tex.first_layer; 208bf215546Sopenharmony_ci desc.Texture2DArray.ArraySize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1; 209bf215546Sopenharmony_ci desc.Texture2DArray.PlaneSlice = 0; 210bf215546Sopenharmony_ci break; 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci case D3D12_RTV_DIMENSION_TEXTURE3D: 213bf215546Sopenharmony_ci desc.Texture3D.MipSlice = tpl->u.tex.level; 214bf215546Sopenharmony_ci desc.Texture3D.FirstWSlice = tpl->u.tex.first_layer; 215bf215546Sopenharmony_ci desc.Texture3D.WSize = tpl->u.tex.last_layer - tpl->u.tex.first_layer + 1; 216bf215546Sopenharmony_ci break; 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci default: 219bf215546Sopenharmony_ci unreachable("Unhandled RTV dimension"); 220bf215546Sopenharmony_ci } 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci mtx_lock(&screen->descriptor_pool_mutex); 223bf215546Sopenharmony_ci d3d12_descriptor_pool_alloc_handle(screen->rtv_pool, handle); 224bf215546Sopenharmony_ci mtx_unlock(&screen->descriptor_pool_mutex); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci screen->dev->CreateRenderTargetView(d3d12_resource_resource(res), &desc, 227bf215546Sopenharmony_ci handle->cpu_handle); 228bf215546Sopenharmony_ci} 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_cistatic struct pipe_surface * 231bf215546Sopenharmony_cid3d12_create_surface(struct pipe_context *pctx, 232bf215546Sopenharmony_ci struct pipe_resource *pres, 233bf215546Sopenharmony_ci const struct pipe_surface *tpl) 234bf215546Sopenharmony_ci{ 235bf215546Sopenharmony_ci bool is_depth_or_stencil = util_format_is_depth_or_stencil(tpl->format); 236bf215546Sopenharmony_ci unsigned bind = is_depth_or_stencil ? PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci /* Don't bother if we don't support the requested format as RT or DS */ 239bf215546Sopenharmony_ci if (!pctx->screen->is_format_supported(pctx->screen, tpl->format, PIPE_TEXTURE_2D, 240bf215546Sopenharmony_ci tpl->nr_samples, tpl->nr_samples,bind)) 241bf215546Sopenharmony_ci return NULL; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci struct d3d12_surface *surface = CALLOC_STRUCT(d3d12_surface); 244bf215546Sopenharmony_ci if (!surface) 245bf215546Sopenharmony_ci return NULL; 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci pipe_resource_reference(&surface->base.texture, pres); 248bf215546Sopenharmony_ci pipe_reference_init(&surface->base.reference, 1); 249bf215546Sopenharmony_ci surface->base.context = pctx; 250bf215546Sopenharmony_ci surface->base.format = tpl->format; 251bf215546Sopenharmony_ci surface->base.width = u_minify(pres->width0, tpl->u.tex.level); 252bf215546Sopenharmony_ci surface->base.height = u_minify(pres->height0, tpl->u.tex.level); 253bf215546Sopenharmony_ci surface->base.u.tex.level = tpl->u.tex.level; 254bf215546Sopenharmony_ci surface->base.u.tex.first_layer = tpl->u.tex.first_layer; 255bf215546Sopenharmony_ci surface->base.u.tex.last_layer = tpl->u.tex.last_layer; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci DXGI_FORMAT dxgi_format = d3d12_get_resource_rt_format(tpl->format); 258bf215546Sopenharmony_ci if (is_depth_or_stencil) 259bf215546Sopenharmony_ci initialize_dsv(pctx, pres, tpl, &surface->desc_handle, dxgi_format); 260bf215546Sopenharmony_ci else 261bf215546Sopenharmony_ci initialize_rtv(pctx, pres, tpl, &surface->desc_handle, dxgi_format); 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci return &surface->base; 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_cistatic void 267bf215546Sopenharmony_cid3d12_surface_destroy(struct pipe_context *pctx, 268bf215546Sopenharmony_ci struct pipe_surface *psurf) 269bf215546Sopenharmony_ci{ 270bf215546Sopenharmony_ci struct d3d12_surface *surface = (struct d3d12_surface*) psurf; 271bf215546Sopenharmony_ci struct d3d12_screen *screen = d3d12_screen(pctx->screen); 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci mtx_lock(&screen->descriptor_pool_mutex); 274bf215546Sopenharmony_ci d3d12_descriptor_handle_free(&surface->desc_handle); 275bf215546Sopenharmony_ci if (d3d12_descriptor_handle_is_allocated(&surface->uint_rtv_handle)) 276bf215546Sopenharmony_ci d3d12_descriptor_handle_free(&surface->uint_rtv_handle); 277bf215546Sopenharmony_ci mtx_unlock(&screen->descriptor_pool_mutex); 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci pipe_resource_reference(&psurf->texture, NULL); 280bf215546Sopenharmony_ci pipe_resource_reference(&surface->rgba_texture, NULL); 281bf215546Sopenharmony_ci FREE(surface); 282bf215546Sopenharmony_ci} 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_cistatic void 285bf215546Sopenharmony_ciblit_surface(struct pipe_context *pctx, struct d3d12_surface *surface, bool pre) 286bf215546Sopenharmony_ci{ 287bf215546Sopenharmony_ci struct pipe_blit_info info = {}; 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci info.src.resource = pre ? surface->base.texture : surface->rgba_texture; 290bf215546Sopenharmony_ci info.dst.resource = pre ? surface->rgba_texture : surface->base.texture; 291bf215546Sopenharmony_ci info.src.format = pre ? surface->base.texture->format : PIPE_FORMAT_R8G8B8A8_UNORM; 292bf215546Sopenharmony_ci info.dst.format = pre ? PIPE_FORMAT_R8G8B8A8_UNORM : surface->base.texture->format; 293bf215546Sopenharmony_ci info.src.level = info.dst.level = 0; 294bf215546Sopenharmony_ci info.src.box.x = info.dst.box.x = 0; 295bf215546Sopenharmony_ci info.src.box.y = info.dst.box.y = 0; 296bf215546Sopenharmony_ci info.src.box.z = info.dst.box.z = 0; 297bf215546Sopenharmony_ci info.src.box.width = info.dst.box.width = surface->base.width; 298bf215546Sopenharmony_ci info.src.box.height = info.dst.box.height = surface->base.height; 299bf215546Sopenharmony_ci info.src.box.depth = info.dst.box.depth = 0; 300bf215546Sopenharmony_ci info.mask = PIPE_MASK_RGBA; 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci d3d12_blit(pctx, &info); 303bf215546Sopenharmony_ci} 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_cienum d3d12_surface_conversion_mode 306bf215546Sopenharmony_cid3d12_surface_update_pre_draw(struct pipe_context *pctx, 307bf215546Sopenharmony_ci struct d3d12_surface *surface, 308bf215546Sopenharmony_ci DXGI_FORMAT format) 309bf215546Sopenharmony_ci{ 310bf215546Sopenharmony_ci struct d3d12_screen *screen = d3d12_screen(surface->base.context->screen); 311bf215546Sopenharmony_ci struct d3d12_resource *res = d3d12_resource(surface->base.texture); 312bf215546Sopenharmony_ci DXGI_FORMAT dxgi_format = d3d12_get_resource_rt_format(surface->base.format); 313bf215546Sopenharmony_ci enum d3d12_surface_conversion_mode mode; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci if (dxgi_format == format) 316bf215546Sopenharmony_ci return D3D12_SURFACE_CONVERSION_NONE; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci if (dxgi_format == DXGI_FORMAT_B8G8R8A8_UNORM || 319bf215546Sopenharmony_ci dxgi_format == DXGI_FORMAT_B8G8R8X8_UNORM) 320bf215546Sopenharmony_ci mode = D3D12_SURFACE_CONVERSION_BGRA_UINT; 321bf215546Sopenharmony_ci else 322bf215546Sopenharmony_ci mode = D3D12_SURFACE_CONVERSION_RGBA_UINT; 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci if (mode == D3D12_SURFACE_CONVERSION_BGRA_UINT) { 325bf215546Sopenharmony_ci if (!surface->rgba_texture) { 326bf215546Sopenharmony_ci struct pipe_resource templ = {}; 327bf215546Sopenharmony_ci struct pipe_resource *src = surface->base.texture; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; 330bf215546Sopenharmony_ci templ.width0 = src->width0; 331bf215546Sopenharmony_ci templ.height0 = src->height0; 332bf215546Sopenharmony_ci templ.depth0 = src->depth0; 333bf215546Sopenharmony_ci templ.array_size = src->array_size; 334bf215546Sopenharmony_ci templ.nr_samples = src->nr_samples; 335bf215546Sopenharmony_ci templ.nr_storage_samples = src->nr_storage_samples; 336bf215546Sopenharmony_ci templ.usage = PIPE_USAGE_DEFAULT | PIPE_USAGE_STAGING; 337bf215546Sopenharmony_ci templ.bind = src->bind; 338bf215546Sopenharmony_ci templ.target = src->target; 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci surface->rgba_texture = screen->base.resource_create(&screen->base, &templ); 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci blit_surface(pctx, surface, true); 344bf215546Sopenharmony_ci res = d3d12_resource(surface->rgba_texture); 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci if (!d3d12_descriptor_handle_is_allocated(&surface->uint_rtv_handle)) { 348bf215546Sopenharmony_ci initialize_rtv(surface->base.context, &res->base.b, &surface->base, 349bf215546Sopenharmony_ci &surface->uint_rtv_handle, DXGI_FORMAT_R8G8B8A8_UINT); 350bf215546Sopenharmony_ci } 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci return mode; 353bf215546Sopenharmony_ci} 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_civoid 356bf215546Sopenharmony_cid3d12_surface_update_post_draw(struct pipe_context *pctx, 357bf215546Sopenharmony_ci struct d3d12_surface *surface, 358bf215546Sopenharmony_ci enum d3d12_surface_conversion_mode mode) 359bf215546Sopenharmony_ci{ 360bf215546Sopenharmony_ci if (mode == D3D12_SURFACE_CONVERSION_BGRA_UINT) 361bf215546Sopenharmony_ci blit_surface(pctx, surface, false); 362bf215546Sopenharmony_ci} 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ciD3D12_CPU_DESCRIPTOR_HANDLE 365bf215546Sopenharmony_cid3d12_surface_get_handle(struct d3d12_surface *surface, 366bf215546Sopenharmony_ci enum d3d12_surface_conversion_mode mode) 367bf215546Sopenharmony_ci{ 368bf215546Sopenharmony_ci if (mode != D3D12_SURFACE_CONVERSION_NONE) 369bf215546Sopenharmony_ci return surface->uint_rtv_handle.cpu_handle; 370bf215546Sopenharmony_ci return surface->desc_handle.cpu_handle; 371bf215546Sopenharmony_ci} 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_civoid 374bf215546Sopenharmony_cid3d12_context_surface_init(struct pipe_context *context) 375bf215546Sopenharmony_ci{ 376bf215546Sopenharmony_ci context->create_surface = d3d12_create_surface; 377bf215546Sopenharmony_ci context->surface_destroy = d3d12_surface_destroy; 378bf215546Sopenharmony_ci} 379