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_compiler.h" 26bf215546Sopenharmony_ci#include "d3d12_debug.h" 27bf215546Sopenharmony_ci#include "d3d12_format.h" 28bf215546Sopenharmony_ci#include "d3d12_query.h" 29bf215546Sopenharmony_ci#include "d3d12_resource.h" 30bf215546Sopenharmony_ci#include "d3d12_screen.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "util/u_blitter.h" 33bf215546Sopenharmony_ci#include "util/format/u_format.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include "nir_to_dxil.h" 36bf215546Sopenharmony_ci#include "nir_builder.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_cistatic void 39bf215546Sopenharmony_cicopy_buffer_region_no_barriers(struct d3d12_context *ctx, 40bf215546Sopenharmony_ci struct d3d12_resource *dst, 41bf215546Sopenharmony_ci uint64_t dst_offset, 42bf215546Sopenharmony_ci struct d3d12_resource *src, 43bf215546Sopenharmony_ci uint64_t src_offset, 44bf215546Sopenharmony_ci uint64_t size) 45bf215546Sopenharmony_ci{ 46bf215546Sopenharmony_ci uint64_t dst_off, src_off; 47bf215546Sopenharmony_ci ID3D12Resource *dst_buf = d3d12_resource_underlying(dst, &dst_off); 48bf215546Sopenharmony_ci ID3D12Resource *src_buf = d3d12_resource_underlying(src, &src_off); 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci ctx->cmdlist->CopyBufferRegion(dst_buf, dst_offset + dst_off, 51bf215546Sopenharmony_ci src_buf, src_offset + src_off, 52bf215546Sopenharmony_ci size); 53bf215546Sopenharmony_ci} 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_cistatic bool 56bf215546Sopenharmony_ciis_resolve(const struct pipe_blit_info *info) 57bf215546Sopenharmony_ci{ 58bf215546Sopenharmony_ci return info->src.resource->nr_samples > 1 && 59bf215546Sopenharmony_ci info->dst.resource->nr_samples <= 1; 60bf215546Sopenharmony_ci} 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_cistatic bool 63bf215546Sopenharmony_ciresolve_supported(const struct pipe_blit_info *info) 64bf215546Sopenharmony_ci{ 65bf215546Sopenharmony_ci assert(is_resolve(info)); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci // check for unsupported operations 68bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(info->src.format) && 69bf215546Sopenharmony_ci info->mask != PIPE_MASK_Z) { 70bf215546Sopenharmony_ci return false; 71bf215546Sopenharmony_ci } else { 72bf215546Sopenharmony_ci if (util_format_get_mask(info->dst.format) != info->mask || 73bf215546Sopenharmony_ci util_format_get_mask(info->src.format) != info->mask || 74bf215546Sopenharmony_ci util_format_has_alpha1(info->src.format)) 75bf215546Sopenharmony_ci return false; 76bf215546Sopenharmony_ci } 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci if (info->filter != PIPE_TEX_FILTER_NEAREST || 79bf215546Sopenharmony_ci info->scissor_enable || 80bf215546Sopenharmony_ci info->num_window_rectangles > 0 || 81bf215546Sopenharmony_ci info->alpha_blend) 82bf215546Sopenharmony_ci return false; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci // formats need to match 85bf215546Sopenharmony_ci struct d3d12_resource *src = d3d12_resource(info->src.resource); 86bf215546Sopenharmony_ci struct d3d12_resource *dst = d3d12_resource(info->dst.resource); 87bf215546Sopenharmony_ci if (src->dxgi_format != dst->dxgi_format) 88bf215546Sopenharmony_ci return false; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci if (util_format_is_pure_integer(src->base.b.format)) 91bf215546Sopenharmony_ci return false; 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci // sizes needs to match 94bf215546Sopenharmony_ci if (info->src.box.width != info->dst.box.width || 95bf215546Sopenharmony_ci info->src.box.height != info->dst.box.height) 96bf215546Sopenharmony_ci return false; 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci // can only resolve full subresource 99bf215546Sopenharmony_ci if (info->src.box.width != (int)u_minify(info->src.resource->width0, 100bf215546Sopenharmony_ci info->src.level) || 101bf215546Sopenharmony_ci info->src.box.height != (int)u_minify(info->src.resource->height0, 102bf215546Sopenharmony_ci info->src.level) || 103bf215546Sopenharmony_ci info->dst.box.width != (int)u_minify(info->dst.resource->width0, 104bf215546Sopenharmony_ci info->dst.level) || 105bf215546Sopenharmony_ci info->dst.box.height != (int)u_minify(info->dst.resource->height0, 106bf215546Sopenharmony_ci info->dst.level)) 107bf215546Sopenharmony_ci return false; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci return true; 110bf215546Sopenharmony_ci} 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_cistatic void 113bf215546Sopenharmony_ciblit_resolve(struct d3d12_context *ctx, const struct pipe_blit_info *info) 114bf215546Sopenharmony_ci{ 115bf215546Sopenharmony_ci struct d3d12_batch *batch = d3d12_current_batch(ctx); 116bf215546Sopenharmony_ci struct d3d12_resource *src = d3d12_resource(info->src.resource); 117bf215546Sopenharmony_ci struct d3d12_resource *dst = d3d12_resource(info->dst.resource); 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci d3d12_transition_resource_state(ctx, src, 120bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_RESOLVE_SOURCE, 121bf215546Sopenharmony_ci D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS); 122bf215546Sopenharmony_ci d3d12_transition_resource_state(ctx, dst, 123bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_RESOLVE_DEST, 124bf215546Sopenharmony_ci D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci d3d12_apply_resource_states(ctx, false); 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci d3d12_batch_reference_resource(batch, src, false); 129bf215546Sopenharmony_ci d3d12_batch_reference_resource(batch, dst, true); 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci DXGI_FORMAT dxgi_format = d3d12_get_resource_srv_format(src->base.b.format, src->base.b.target); 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci assert(src->dxgi_format == dst->dxgi_format); 134bf215546Sopenharmony_ci ctx->cmdlist->ResolveSubresource( 135bf215546Sopenharmony_ci d3d12_resource_resource(dst), info->dst.level, 136bf215546Sopenharmony_ci d3d12_resource_resource(src), info->src.level, 137bf215546Sopenharmony_ci dxgi_format); 138bf215546Sopenharmony_ci} 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_cistatic bool 141bf215546Sopenharmony_ciformats_are_copy_compatible(enum pipe_format src, enum pipe_format dst) 142bf215546Sopenharmony_ci{ 143bf215546Sopenharmony_ci if (src == dst) 144bf215546Sopenharmony_ci return true; 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci /* We can skip the stencil copy */ 147bf215546Sopenharmony_ci if (util_format_get_depth_only(src) == dst || 148bf215546Sopenharmony_ci util_format_get_depth_only(dst) == src) 149bf215546Sopenharmony_ci return true; 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci return false; 152bf215546Sopenharmony_ci} 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_cistatic bool 155bf215546Sopenharmony_cibox_fits(const struct pipe_box *box, const struct pipe_resource *res, int level) 156bf215546Sopenharmony_ci{ 157bf215546Sopenharmony_ci unsigned lwidth = u_minify(res->width0, level); 158bf215546Sopenharmony_ci unsigned lheight= u_minify(res->height0, level); 159bf215546Sopenharmony_ci unsigned ldepth = res->target == PIPE_TEXTURE_3D ? u_minify(res->depth0, level) : 160bf215546Sopenharmony_ci res->array_size; 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci unsigned wb = box->x; 163bf215546Sopenharmony_ci unsigned we = box->x + box->width; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci unsigned hb = box->y; 166bf215546Sopenharmony_ci unsigned he = box->y + box->height; 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci unsigned db = box->z; 169bf215546Sopenharmony_ci unsigned de = box->z + box->depth; 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci return (wb <= lwidth && we <= lwidth && 172bf215546Sopenharmony_ci hb <= lheight && he <= lheight && 173bf215546Sopenharmony_ci db <= ldepth && de <= ldepth); 174bf215546Sopenharmony_ci} 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_cistatic bool 177bf215546Sopenharmony_cidirect_copy_supported(struct d3d12_screen *screen, 178bf215546Sopenharmony_ci const struct pipe_blit_info *info, 179bf215546Sopenharmony_ci bool have_predication) 180bf215546Sopenharmony_ci{ 181bf215546Sopenharmony_ci if (info->scissor_enable || info->alpha_blend || 182bf215546Sopenharmony_ci (have_predication && info->render_condition_enable) || 183bf215546Sopenharmony_ci MAX2(info->src.resource->nr_samples, 1) != MAX2(info->dst.resource->nr_samples, 1)) { 184bf215546Sopenharmony_ci return false; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci if (!formats_are_copy_compatible(info->src.format, info->dst.format)) 188bf215546Sopenharmony_ci return false; 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(info->src.format) && !(info->mask & PIPE_MASK_ZS)) { 191bf215546Sopenharmony_ci return false; 192bf215546Sopenharmony_ci } 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if (!util_format_is_depth_or_stencil(info->src.format)) { 195bf215546Sopenharmony_ci if (util_format_get_mask(info->dst.format) != info->mask || 196bf215546Sopenharmony_ci util_format_get_mask(info->src.format) != info->mask) 197bf215546Sopenharmony_ci return false; 198bf215546Sopenharmony_ci } 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci if (abs(info->src.box.height) != info->dst.box.height) { 201bf215546Sopenharmony_ci return false; 202bf215546Sopenharmony_ci } 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci if (info->src.box.height != info->dst.box.height && 205bf215546Sopenharmony_ci (!util_format_is_depth_or_stencil(info->src.format) || 206bf215546Sopenharmony_ci screen->opts2.ProgrammableSamplePositionsTier == 207bf215546Sopenharmony_ci D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED)) { 208bf215546Sopenharmony_ci return false; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci if (!box_fits(&info->dst.box, info->dst.resource, info->dst.level)) { 212bf215546Sopenharmony_ci return false; 213bf215546Sopenharmony_ci } 214bf215546Sopenharmony_ci if (!box_fits(&info->src.box, info->src.resource, info->src.level)) { 215bf215546Sopenharmony_ci return false; 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci if (info->src.box.width != info->dst.box.width) { 219bf215546Sopenharmony_ci return false; 220bf215546Sopenharmony_ci } 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci if (info->src.box.depth != info->dst.box.depth) { 223bf215546Sopenharmony_ci return false; 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci if ((screen->opts2.ProgrammableSamplePositionsTier == 227bf215546Sopenharmony_ci D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED && 228bf215546Sopenharmony_ci (info->src.resource->bind & PIPE_BIND_DEPTH_STENCIL || 229bf215546Sopenharmony_ci info->dst.resource->bind & PIPE_BIND_DEPTH_STENCIL)) || 230bf215546Sopenharmony_ci info->src.resource->nr_samples != info->dst.resource->nr_samples) { 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci if (info->dst.box.x != 0 || 233bf215546Sopenharmony_ci info->dst.box.y != 0 || 234bf215546Sopenharmony_ci info->dst.box.z != 0) 235bf215546Sopenharmony_ci return false; 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci if (info->src.box.x != 0 || 238bf215546Sopenharmony_ci info->src.box.y != 0 || 239bf215546Sopenharmony_ci info->src.box.z != 0 || 240bf215546Sopenharmony_ci info->src.box.width != (int)u_minify(info->src.resource->width0, 241bf215546Sopenharmony_ci info->src.level) || 242bf215546Sopenharmony_ci info->src.box.height != (int)u_minify(info->src.resource->height0, 243bf215546Sopenharmony_ci info->src.level) || 244bf215546Sopenharmony_ci info->src.box.depth != (int)u_minify(info->src.resource->depth0, 245bf215546Sopenharmony_ci info->src.level)) 246bf215546Sopenharmony_ci return false; 247bf215546Sopenharmony_ci } 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci return true; 250bf215546Sopenharmony_ci} 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ciinline static unsigned 253bf215546Sopenharmony_ciget_subresource_id(enum pipe_texture_target target, unsigned subres, unsigned stride, 254bf215546Sopenharmony_ci unsigned z, unsigned *updated_z, unsigned array_size, unsigned plane_slice) 255bf215546Sopenharmony_ci{ 256bf215546Sopenharmony_ci if (d3d12_subresource_id_uses_layer(target)) { 257bf215546Sopenharmony_ci subres += stride * z; 258bf215546Sopenharmony_ci if (updated_z) 259bf215546Sopenharmony_ci *updated_z = 0; 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci return subres + plane_slice * array_size * stride; 262bf215546Sopenharmony_ci} 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_cistatic void 265bf215546Sopenharmony_cicopy_subregion_no_barriers(struct d3d12_context *ctx, 266bf215546Sopenharmony_ci struct d3d12_resource *dst, 267bf215546Sopenharmony_ci unsigned dst_level, 268bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned dstz, 269bf215546Sopenharmony_ci struct d3d12_resource *src, 270bf215546Sopenharmony_ci unsigned src_level, 271bf215546Sopenharmony_ci const struct pipe_box *psrc_box, 272bf215546Sopenharmony_ci unsigned mask) 273bf215546Sopenharmony_ci{ 274bf215546Sopenharmony_ci UNUSED struct d3d12_screen *screen = d3d12_screen(ctx->base.screen); 275bf215546Sopenharmony_ci D3D12_TEXTURE_COPY_LOCATION src_loc, dst_loc; 276bf215546Sopenharmony_ci unsigned src_z = psrc_box->z; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci int src_subres_stride = src->base.b.last_level + 1; 279bf215546Sopenharmony_ci int dst_subres_stride = dst->base.b.last_level + 1; 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci int src_array_size = src->base.b.array_size; 282bf215546Sopenharmony_ci int dst_array_size = dst->base.b.array_size; 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci if (dst->base.b.target == PIPE_TEXTURE_CUBE) 285bf215546Sopenharmony_ci dst_array_size *= 6; 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci if (src->base.b.target == PIPE_TEXTURE_CUBE) 288bf215546Sopenharmony_ci src_array_size *= 6; 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci int stencil_src_res_offset = 1; 291bf215546Sopenharmony_ci int stencil_dst_res_offset = 1; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci int src_nres = 1; 294bf215546Sopenharmony_ci int dst_nres = 1; 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci if (dst->base.b.format == PIPE_FORMAT_Z24_UNORM_S8_UINT || 297bf215546Sopenharmony_ci dst->base.b.format == PIPE_FORMAT_S8_UINT_Z24_UNORM || 298bf215546Sopenharmony_ci dst->base.b.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { 299bf215546Sopenharmony_ci stencil_dst_res_offset = dst_subres_stride * dst_array_size; 300bf215546Sopenharmony_ci src_nres = 2; 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci if (src->base.b.format == PIPE_FORMAT_Z24_UNORM_S8_UINT || 304bf215546Sopenharmony_ci src->base.b.format == PIPE_FORMAT_S8_UINT_Z24_UNORM || 305bf215546Sopenharmony_ci dst->base.b.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { 306bf215546Sopenharmony_ci stencil_src_res_offset = src_subres_stride * src_array_size; 307bf215546Sopenharmony_ci dst_nres = 2; 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci static_assert(PIPE_MASK_S == 0x20 && PIPE_MASK_Z == 0x10, "unexpected ZS format mask"); 311bf215546Sopenharmony_ci int nsubres = MIN2(src_nres, dst_nres); 312bf215546Sopenharmony_ci unsigned subresource_copy_mask = nsubres > 1 ? mask >> 4 : 1; 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci for (int subres = 0; subres < nsubres; ++subres) { 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci if (!(subresource_copy_mask & (1 << subres))) 317bf215546Sopenharmony_ci continue; 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci src_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; 320bf215546Sopenharmony_ci src_loc.SubresourceIndex = get_subresource_id(src->base.b.target, src_level, src_subres_stride, src_z, &src_z, src_array_size, src->plane_slice) + 321bf215546Sopenharmony_ci subres * stencil_src_res_offset; 322bf215546Sopenharmony_ci src_loc.pResource = d3d12_resource_resource(src); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; 325bf215546Sopenharmony_ci dst_loc.SubresourceIndex = get_subresource_id(dst->base.b.target, dst_level, dst_subres_stride, dstz, &dstz, dst_array_size, dst->plane_slice) + 326bf215546Sopenharmony_ci subres * stencil_dst_res_offset; 327bf215546Sopenharmony_ci dst_loc.pResource = d3d12_resource_resource(dst); 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci if (psrc_box->x == 0 && psrc_box->y == 0 && psrc_box->z == 0 && 330bf215546Sopenharmony_ci psrc_box->width == (int)u_minify(src->base.b.width0, src_level) && 331bf215546Sopenharmony_ci psrc_box->height == (int)u_minify(src->base.b.height0, src_level) && 332bf215546Sopenharmony_ci psrc_box->depth == (int)u_minify(src->base.b.depth0, src_level)) { 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci assert((dstx == 0 && dsty == 0 && dstz == 0) || 335bf215546Sopenharmony_ci screen->opts2.ProgrammableSamplePositionsTier != 336bf215546Sopenharmony_ci D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED || 337bf215546Sopenharmony_ci (!util_format_is_depth_or_stencil(dst->base.b.format) && 338bf215546Sopenharmony_ci !util_format_is_depth_or_stencil(src->base.b.format) && 339bf215546Sopenharmony_ci dst->base.b.nr_samples == src->base.b.nr_samples)); 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci ctx->cmdlist->CopyTextureRegion(&dst_loc, dstx, dsty, dstz, 342bf215546Sopenharmony_ci &src_loc, NULL); 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci } else { 345bf215546Sopenharmony_ci D3D12_BOX src_box; 346bf215546Sopenharmony_ci src_box.left = psrc_box->x; 347bf215546Sopenharmony_ci src_box.right = MIN2(psrc_box->x + psrc_box->width, (int)u_minify(src->base.b.width0, src_level)); 348bf215546Sopenharmony_ci src_box.top = psrc_box->y; 349bf215546Sopenharmony_ci src_box.bottom = MIN2(psrc_box->y + psrc_box->height, (int)u_minify(src->base.b.height0, src_level)); 350bf215546Sopenharmony_ci src_box.front = src_z; 351bf215546Sopenharmony_ci src_box.back = src_z + psrc_box->depth; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci assert((screen->opts2.ProgrammableSamplePositionsTier != 354bf215546Sopenharmony_ci D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED || 355bf215546Sopenharmony_ci (!util_format_is_depth_or_stencil(dst->base.b.format) && 356bf215546Sopenharmony_ci !util_format_is_depth_or_stencil(src->base.b.format))) && 357bf215546Sopenharmony_ci dst->base.b.nr_samples == src->base.b.nr_samples); 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci ctx->cmdlist->CopyTextureRegion(&dst_loc, dstx, dsty, dstz, 360bf215546Sopenharmony_ci &src_loc, &src_box); 361bf215546Sopenharmony_ci } 362bf215546Sopenharmony_ci } 363bf215546Sopenharmony_ci} 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_cistatic void 366bf215546Sopenharmony_cicopy_resource_y_flipped_no_barriers(struct d3d12_context *ctx, 367bf215546Sopenharmony_ci struct d3d12_resource *dst, 368bf215546Sopenharmony_ci unsigned dst_level, 369bf215546Sopenharmony_ci const struct pipe_box *pdst_box, 370bf215546Sopenharmony_ci struct d3d12_resource *src, 371bf215546Sopenharmony_ci unsigned src_level, 372bf215546Sopenharmony_ci const struct pipe_box *psrc_box, 373bf215546Sopenharmony_ci unsigned mask) 374bf215546Sopenharmony_ci{ 375bf215546Sopenharmony_ci if (D3D12_DEBUG_BLIT & d3d12_debug) { 376bf215546Sopenharmony_ci debug_printf("D3D12 BLIT as COPY: from %s@%d %dx%dx%d + %dx%dx%d\n", 377bf215546Sopenharmony_ci util_format_name(src->base.b.format), src_level, 378bf215546Sopenharmony_ci psrc_box->x, psrc_box->y, psrc_box->z, 379bf215546Sopenharmony_ci psrc_box->width, psrc_box->height, psrc_box->depth); 380bf215546Sopenharmony_ci debug_printf(" to %s@%d %dx%dx%d\n", 381bf215546Sopenharmony_ci util_format_name(dst->base.b.format), dst_level, 382bf215546Sopenharmony_ci pdst_box->x, pdst_box->y, pdst_box->z); 383bf215546Sopenharmony_ci } 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci struct pipe_box src_box = *psrc_box; 386bf215546Sopenharmony_ci int src_inc = psrc_box->height > 0 ? 1 : -1; 387bf215546Sopenharmony_ci int dst_inc = pdst_box->height > 0 ? 1 : -1; 388bf215546Sopenharmony_ci src_box.height = 1; 389bf215546Sopenharmony_ci int rows_to_copy = abs(psrc_box->height); 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci if (psrc_box->height < 0) 392bf215546Sopenharmony_ci --src_box.y; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci for (int y = 0, dest_y = pdst_box->y; y < rows_to_copy; 395bf215546Sopenharmony_ci ++y, src_box.y += src_inc, dest_y += dst_inc) { 396bf215546Sopenharmony_ci copy_subregion_no_barriers(ctx, dst, dst_level, 397bf215546Sopenharmony_ci pdst_box->x, dest_y, pdst_box->z, 398bf215546Sopenharmony_ci src, src_level, &src_box, mask); 399bf215546Sopenharmony_ci } 400bf215546Sopenharmony_ci} 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_civoid 403bf215546Sopenharmony_cid3d12_direct_copy(struct d3d12_context *ctx, 404bf215546Sopenharmony_ci struct d3d12_resource *dst, 405bf215546Sopenharmony_ci unsigned dst_level, 406bf215546Sopenharmony_ci const struct pipe_box *pdst_box, 407bf215546Sopenharmony_ci struct d3d12_resource *src, 408bf215546Sopenharmony_ci unsigned src_level, 409bf215546Sopenharmony_ci const struct pipe_box *psrc_box, 410bf215546Sopenharmony_ci unsigned mask) 411bf215546Sopenharmony_ci{ 412bf215546Sopenharmony_ci struct d3d12_batch *batch = d3d12_current_batch(ctx); 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci unsigned src_subres = get_subresource_id(src->base.b.target, src_level, src->base.b.last_level + 1, 415bf215546Sopenharmony_ci psrc_box->z, nullptr, src->base.b.array_size, src->plane_slice); 416bf215546Sopenharmony_ci unsigned dst_subres = get_subresource_id(dst->base.b.target, dst_level, dst->base.b.last_level + 1, 417bf215546Sopenharmony_ci pdst_box->z, nullptr, dst->base.b.array_size, dst->plane_slice); 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci if (D3D12_DEBUG_BLIT & d3d12_debug) 420bf215546Sopenharmony_ci debug_printf("BLIT: Direct copy from subres %d to subres %d\n", 421bf215546Sopenharmony_ci src_subres, dst_subres); 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci d3d12_transition_subresources_state(ctx, src, src_subres, 1, 0, 1, 424bf215546Sopenharmony_ci d3d12_get_format_start_plane(src->base.b.format), 425bf215546Sopenharmony_ci d3d12_get_format_num_planes(src->base.b.format), 426bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_COPY_SOURCE, 427bf215546Sopenharmony_ci D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci d3d12_transition_subresources_state(ctx, dst, dst_subres, 1, 0, 1, 430bf215546Sopenharmony_ci d3d12_get_format_start_plane(dst->base.b.format), 431bf215546Sopenharmony_ci d3d12_get_format_num_planes(dst->base.b.format), 432bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_COPY_DEST, 433bf215546Sopenharmony_ci D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS); 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci d3d12_apply_resource_states(ctx, false); 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci d3d12_batch_reference_resource(batch, src, false); 438bf215546Sopenharmony_ci d3d12_batch_reference_resource(batch, dst, true); 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci if (src->base.b.target == PIPE_BUFFER) { 441bf215546Sopenharmony_ci copy_buffer_region_no_barriers(ctx, dst, pdst_box->x, 442bf215546Sopenharmony_ci src, psrc_box->x, psrc_box->width); 443bf215546Sopenharmony_ci } else if (psrc_box->height == pdst_box->height) { 444bf215546Sopenharmony_ci /* No flipping, we can forward this directly to resource_copy_region */ 445bf215546Sopenharmony_ci copy_subregion_no_barriers(ctx, dst, dst_level, 446bf215546Sopenharmony_ci pdst_box->x, pdst_box->y, pdst_box->z, 447bf215546Sopenharmony_ci src, src_level, psrc_box, mask); 448bf215546Sopenharmony_ci } else { 449bf215546Sopenharmony_ci assert(psrc_box->height == -pdst_box->height); 450bf215546Sopenharmony_ci copy_resource_y_flipped_no_barriers(ctx, dst, dst_level, pdst_box, 451bf215546Sopenharmony_ci src, src_level, psrc_box, mask); 452bf215546Sopenharmony_ci } 453bf215546Sopenharmony_ci} 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_cistatic bool 456bf215546Sopenharmony_ciis_same_resource(const struct pipe_blit_info *info) 457bf215546Sopenharmony_ci{ 458bf215546Sopenharmony_ci return d3d12_resource_resource(d3d12_resource(info->src.resource)) == 459bf215546Sopenharmony_ci d3d12_resource_resource(d3d12_resource(info->dst.resource)) && 460bf215546Sopenharmony_ci info->src.level == info->dst.level; 461bf215546Sopenharmony_ci} 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_cistatic struct pipe_resource * 464bf215546Sopenharmony_cicreate_staging_resource(struct d3d12_context *ctx, 465bf215546Sopenharmony_ci struct d3d12_resource *src, 466bf215546Sopenharmony_ci unsigned src_level, 467bf215546Sopenharmony_ci const struct pipe_box *src_box, 468bf215546Sopenharmony_ci struct pipe_box *dst_box, 469bf215546Sopenharmony_ci unsigned mask) 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci{ 472bf215546Sopenharmony_ci struct pipe_resource templ = {}; 473bf215546Sopenharmony_ci struct pipe_resource *staging_res; 474bf215546Sopenharmony_ci struct pipe_box copy_src; 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci u_box_3d(MIN2(src_box->x, src_box->x + src_box->width), 477bf215546Sopenharmony_ci MIN2(src_box->y, src_box->y + src_box->height), 478bf215546Sopenharmony_ci MIN2(src_box->z, src_box->z + src_box->depth), 479bf215546Sopenharmony_ci abs(src_box->width), abs(src_box->height), abs(src_box->depth), 480bf215546Sopenharmony_ci ©_src); 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci templ.format = src->base.b.format; 483bf215546Sopenharmony_ci templ.width0 = copy_src.width; 484bf215546Sopenharmony_ci templ.height0 = copy_src.height; 485bf215546Sopenharmony_ci templ.depth0 = copy_src.depth; 486bf215546Sopenharmony_ci templ.array_size = 1; 487bf215546Sopenharmony_ci templ.nr_samples = src->base.b.nr_samples; 488bf215546Sopenharmony_ci templ.nr_storage_samples = src->base.b.nr_storage_samples; 489bf215546Sopenharmony_ci templ.usage = PIPE_USAGE_STAGING; 490bf215546Sopenharmony_ci templ.bind = util_format_is_depth_or_stencil(templ.format) ? PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET; 491bf215546Sopenharmony_ci templ.target = src->base.b.target; 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci staging_res = ctx->base.screen->resource_create(ctx->base.screen, &templ); 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci dst_box->x = 0; 496bf215546Sopenharmony_ci dst_box->y = 0; 497bf215546Sopenharmony_ci dst_box->z = 0; 498bf215546Sopenharmony_ci dst_box->width = copy_src.width; 499bf215546Sopenharmony_ci dst_box->height = copy_src.height; 500bf215546Sopenharmony_ci dst_box->depth = copy_src.depth; 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci d3d12_direct_copy(ctx, d3d12_resource(staging_res), 0, dst_box, 503bf215546Sopenharmony_ci src, src_level, ©_src, mask); 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci if (src_box->width < 0) { 506bf215546Sopenharmony_ci dst_box->x = dst_box->width; 507bf215546Sopenharmony_ci dst_box->width = src_box->width; 508bf215546Sopenharmony_ci } 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci if (src_box->height < 0) { 511bf215546Sopenharmony_ci dst_box->y = dst_box->height; 512bf215546Sopenharmony_ci dst_box->height = src_box->height; 513bf215546Sopenharmony_ci } 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci if (src_box->depth < 0) { 516bf215546Sopenharmony_ci dst_box->z = dst_box->depth; 517bf215546Sopenharmony_ci dst_box->depth = src_box->depth; 518bf215546Sopenharmony_ci } 519bf215546Sopenharmony_ci return staging_res; 520bf215546Sopenharmony_ci} 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_cistatic void 523bf215546Sopenharmony_ciblit_same_resource(struct d3d12_context *ctx, 524bf215546Sopenharmony_ci const struct pipe_blit_info *info) 525bf215546Sopenharmony_ci{ 526bf215546Sopenharmony_ci struct pipe_blit_info dst_info = *info; 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_ci dst_info.src.level = 0; 529bf215546Sopenharmony_ci dst_info.src.resource = create_staging_resource(ctx, d3d12_resource(info->src.resource), 530bf215546Sopenharmony_ci info->src.level, 531bf215546Sopenharmony_ci &info->src.box, 532bf215546Sopenharmony_ci &dst_info.src.box, PIPE_MASK_RGBAZS); 533bf215546Sopenharmony_ci ctx->base.blit(&ctx->base, &dst_info); 534bf215546Sopenharmony_ci pipe_resource_reference(&dst_info.src.resource, NULL); 535bf215546Sopenharmony_ci} 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_cistatic void 538bf215546Sopenharmony_ciutil_blit_save_state(struct d3d12_context *ctx) 539bf215546Sopenharmony_ci{ 540bf215546Sopenharmony_ci util_blitter_save_blend(ctx->blitter, ctx->gfx_pipeline_state.blend); 541bf215546Sopenharmony_ci util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->gfx_pipeline_state.zsa); 542bf215546Sopenharmony_ci util_blitter_save_vertex_elements(ctx->blitter, ctx->gfx_pipeline_state.ves); 543bf215546Sopenharmony_ci util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref); 544bf215546Sopenharmony_ci util_blitter_save_rasterizer(ctx->blitter, ctx->gfx_pipeline_state.rast); 545bf215546Sopenharmony_ci util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]); 546bf215546Sopenharmony_ci util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]); 547bf215546Sopenharmony_ci util_blitter_save_geometry_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_GEOMETRY]); 548bf215546Sopenharmony_ci util_blitter_save_tessctrl_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_TESS_CTRL]); 549bf215546Sopenharmony_ci util_blitter_save_tesseval_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]); 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci util_blitter_save_framebuffer(ctx->blitter, &ctx->fb); 552bf215546Sopenharmony_ci util_blitter_save_viewport(ctx->blitter, ctx->viewport_states); 553bf215546Sopenharmony_ci util_blitter_save_scissor(ctx->blitter, ctx->scissor_states); 554bf215546Sopenharmony_ci util_blitter_save_fragment_sampler_states(ctx->blitter, 555bf215546Sopenharmony_ci ctx->num_samplers[PIPE_SHADER_FRAGMENT], 556bf215546Sopenharmony_ci (void **)ctx->samplers[PIPE_SHADER_FRAGMENT]); 557bf215546Sopenharmony_ci util_blitter_save_fragment_sampler_views(ctx->blitter, 558bf215546Sopenharmony_ci ctx->num_sampler_views[PIPE_SHADER_FRAGMENT], 559bf215546Sopenharmony_ci ctx->sampler_views[PIPE_SHADER_FRAGMENT]); 560bf215546Sopenharmony_ci util_blitter_save_fragment_constant_buffer_slot(ctx->blitter, ctx->cbufs[PIPE_SHADER_FRAGMENT]); 561bf215546Sopenharmony_ci util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vbs); 562bf215546Sopenharmony_ci util_blitter_save_sample_mask(ctx->blitter, ctx->gfx_pipeline_state.sample_mask, 0); 563bf215546Sopenharmony_ci util_blitter_save_so_targets(ctx->blitter, ctx->gfx_pipeline_state.num_so_targets, ctx->so_targets); 564bf215546Sopenharmony_ci} 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_cistatic void 567bf215546Sopenharmony_ciutil_blit(struct d3d12_context *ctx, 568bf215546Sopenharmony_ci const struct pipe_blit_info *info) 569bf215546Sopenharmony_ci{ 570bf215546Sopenharmony_ci util_blit_save_state(ctx); 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci util_blitter_blit(ctx->blitter, info); 573bf215546Sopenharmony_ci} 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_cistatic bool 576bf215546Sopenharmony_ciresolve_stencil_supported(struct d3d12_context *ctx, 577bf215546Sopenharmony_ci const struct pipe_blit_info *info) 578bf215546Sopenharmony_ci{ 579bf215546Sopenharmony_ci assert(is_resolve(info)); 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci if (!util_format_is_depth_or_stencil(info->src.format) || 582bf215546Sopenharmony_ci !(info->mask & PIPE_MASK_S)) 583bf215546Sopenharmony_ci return false; 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci if (info->mask & PIPE_MASK_Z) { 586bf215546Sopenharmony_ci struct pipe_blit_info new_info = *info; 587bf215546Sopenharmony_ci new_info.mask = PIPE_MASK_Z; 588bf215546Sopenharmony_ci if (!resolve_supported(&new_info) && 589bf215546Sopenharmony_ci !util_blitter_is_blit_supported(ctx->blitter, &new_info)) 590bf215546Sopenharmony_ci return false; 591bf215546Sopenharmony_ci } 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci struct pipe_blit_info new_info = *info; 594bf215546Sopenharmony_ci new_info.dst.format = PIPE_FORMAT_R8_UINT; 595bf215546Sopenharmony_ci return util_blitter_is_blit_supported(ctx->blitter, &new_info); 596bf215546Sopenharmony_ci} 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_cistatic struct pipe_resource * 599bf215546Sopenharmony_cicreate_tmp_resource(struct pipe_screen *screen, 600bf215546Sopenharmony_ci const struct pipe_blit_info *info) 601bf215546Sopenharmony_ci{ 602bf215546Sopenharmony_ci struct pipe_resource tpl = {}; 603bf215546Sopenharmony_ci tpl.width0 = info->dst.box.width; 604bf215546Sopenharmony_ci tpl.height0 = info->dst.box.height; 605bf215546Sopenharmony_ci tpl.depth0 = info->dst.box.depth; 606bf215546Sopenharmony_ci tpl.array_size = 1; 607bf215546Sopenharmony_ci tpl.format = PIPE_FORMAT_R8_UINT; 608bf215546Sopenharmony_ci tpl.target = info->dst.resource->target; 609bf215546Sopenharmony_ci tpl.nr_samples = info->dst.resource->nr_samples; 610bf215546Sopenharmony_ci tpl.nr_storage_samples = info->dst.resource->nr_storage_samples; 611bf215546Sopenharmony_ci tpl.usage = PIPE_USAGE_STREAM; 612bf215546Sopenharmony_ci tpl.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; 613bf215546Sopenharmony_ci return screen->resource_create(screen, &tpl); 614bf215546Sopenharmony_ci} 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_cistatic void * 617bf215546Sopenharmony_ciget_stencil_resolve_vs(struct d3d12_context *ctx) 618bf215546Sopenharmony_ci{ 619bf215546Sopenharmony_ci if (ctx->stencil_resolve_vs) 620bf215546Sopenharmony_ci return ctx->stencil_resolve_vs; 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, 623bf215546Sopenharmony_ci &d3d12_screen(ctx->base.screen)->nir_options, 624bf215546Sopenharmony_ci "linear_blit_vs"); 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci const struct glsl_type *vec4 = glsl_vec4_type(); 627bf215546Sopenharmony_ci nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in, 628bf215546Sopenharmony_ci vec4, "pos"); 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out, 631bf215546Sopenharmony_ci vec4, "gl_Position"); 632bf215546Sopenharmony_ci pos_out->data.location = VARYING_SLOT_POS; 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci nir_store_var(&b, pos_out, nir_load_var(&b, pos_in), 0xf); 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_ci struct pipe_shader_state state = {}; 637bf215546Sopenharmony_ci state.type = PIPE_SHADER_IR_NIR; 638bf215546Sopenharmony_ci state.ir.nir = b.shader; 639bf215546Sopenharmony_ci ctx->stencil_resolve_vs = ctx->base.create_vs_state(&ctx->base, &state); 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci return ctx->stencil_resolve_vs; 642bf215546Sopenharmony_ci} 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_cistatic void * 645bf215546Sopenharmony_ciget_stencil_resolve_fs(struct d3d12_context *ctx, bool no_flip) 646bf215546Sopenharmony_ci{ 647bf215546Sopenharmony_ci if (!no_flip && ctx->stencil_resolve_fs) 648bf215546Sopenharmony_ci return ctx->stencil_resolve_fs; 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ci if (no_flip && ctx->stencil_resolve_fs_no_flip) 651bf215546Sopenharmony_ci return ctx->stencil_resolve_fs_no_flip; 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, 654bf215546Sopenharmony_ci &d3d12_screen(ctx->base.screen)->nir_options, 655bf215546Sopenharmony_ci no_flip ? "stencil_resolve_fs_no_flip" : "stencil_resolve_fs"); 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci nir_variable *stencil_out = nir_variable_create(b.shader, 658bf215546Sopenharmony_ci nir_var_shader_out, 659bf215546Sopenharmony_ci glsl_uint_type(), 660bf215546Sopenharmony_ci "stencil_out"); 661bf215546Sopenharmony_ci stencil_out->data.location = FRAG_RESULT_COLOR; 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci const struct glsl_type *sampler_type = 664bf215546Sopenharmony_ci glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, GLSL_TYPE_UINT); 665bf215546Sopenharmony_ci nir_variable *sampler = nir_variable_create(b.shader, nir_var_uniform, 666bf215546Sopenharmony_ci sampler_type, "stencil_tex"); 667bf215546Sopenharmony_ci sampler->data.binding = 0; 668bf215546Sopenharmony_ci sampler->data.explicit_binding = true; 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_ci nir_ssa_def *tex_deref = &nir_build_deref_var(&b, sampler)->dest.ssa; 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in, 673bf215546Sopenharmony_ci glsl_vec4_type(), "pos"); 674bf215546Sopenharmony_ci pos_in->data.location = VARYING_SLOT_POS; // VARYING_SLOT_VAR0? 675bf215546Sopenharmony_ci nir_ssa_def *pos = nir_load_var(&b, pos_in); 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci nir_ssa_def *pos_src; 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci if (no_flip) 680bf215546Sopenharmony_ci pos_src = pos; 681bf215546Sopenharmony_ci else { 682bf215546Sopenharmony_ci nir_tex_instr *txs = nir_tex_instr_create(b.shader, 1); 683bf215546Sopenharmony_ci txs->op = nir_texop_txs; 684bf215546Sopenharmony_ci txs->sampler_dim = GLSL_SAMPLER_DIM_MS; 685bf215546Sopenharmony_ci txs->src[0].src_type = nir_tex_src_texture_deref; 686bf215546Sopenharmony_ci txs->src[0].src = nir_src_for_ssa(tex_deref); 687bf215546Sopenharmony_ci txs->is_array = false; 688bf215546Sopenharmony_ci txs->dest_type = nir_type_int; 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci nir_ssa_dest_init(&txs->instr, &txs->dest, 2, 32, "tex"); 691bf215546Sopenharmony_ci nir_builder_instr_insert(&b, &txs->instr); 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci pos_src = nir_vec4(&b, 694bf215546Sopenharmony_ci nir_channel(&b, pos, 0), 695bf215546Sopenharmony_ci /*Height - pos_dest.y - 1*/ 696bf215546Sopenharmony_ci nir_fsub(&b, 697bf215546Sopenharmony_ci nir_fsub(&b, 698bf215546Sopenharmony_ci nir_channel(&b, nir_i2f32(&b, &txs->dest.ssa), 1), 699bf215546Sopenharmony_ci nir_channel(&b, pos, 1)), 700bf215546Sopenharmony_ci nir_imm_float(&b, 1.0)), 701bf215546Sopenharmony_ci nir_channel(&b, pos, 2), 702bf215546Sopenharmony_ci nir_channel(&b, pos, 3)); 703bf215546Sopenharmony_ci } 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3); 706bf215546Sopenharmony_ci tex->sampler_dim = GLSL_SAMPLER_DIM_MS; 707bf215546Sopenharmony_ci tex->op = nir_texop_txf_ms; 708bf215546Sopenharmony_ci tex->src[0].src_type = nir_tex_src_coord; 709bf215546Sopenharmony_ci tex->src[0].src = nir_src_for_ssa(nir_channels(&b, nir_f2i32(&b, pos_src), 0x3)); 710bf215546Sopenharmony_ci tex->src[1].src_type = nir_tex_src_ms_index; 711bf215546Sopenharmony_ci tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0)); /* just use first sample */ 712bf215546Sopenharmony_ci tex->src[2].src_type = nir_tex_src_texture_deref; 713bf215546Sopenharmony_ci tex->src[2].src = nir_src_for_ssa(tex_deref); 714bf215546Sopenharmony_ci tex->dest_type = nir_type_uint32; 715bf215546Sopenharmony_ci tex->is_array = false; 716bf215546Sopenharmony_ci tex->coord_components = 2; 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ci nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex"); 719bf215546Sopenharmony_ci nir_builder_instr_insert(&b, &tex->instr); 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci nir_store_var(&b, stencil_out, nir_channel(&b, &tex->dest.ssa, 1), 0x1); 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci struct pipe_shader_state state = {}; 724bf215546Sopenharmony_ci state.type = PIPE_SHADER_IR_NIR; 725bf215546Sopenharmony_ci state.ir.nir = b.shader; 726bf215546Sopenharmony_ci void *result; 727bf215546Sopenharmony_ci if (no_flip) { 728bf215546Sopenharmony_ci result = ctx->base.create_fs_state(&ctx->base, &state); 729bf215546Sopenharmony_ci ctx->stencil_resolve_fs_no_flip = result; 730bf215546Sopenharmony_ci } else { 731bf215546Sopenharmony_ci result = ctx->base.create_fs_state(&ctx->base, &state); 732bf215546Sopenharmony_ci ctx->stencil_resolve_fs = result; 733bf215546Sopenharmony_ci } 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci return result; 736bf215546Sopenharmony_ci} 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_cistatic void * 739bf215546Sopenharmony_ciget_sampler_state(struct d3d12_context *ctx) 740bf215546Sopenharmony_ci{ 741bf215546Sopenharmony_ci if (ctx->sampler_state) 742bf215546Sopenharmony_ci return ctx->sampler_state; 743bf215546Sopenharmony_ci 744bf215546Sopenharmony_ci struct pipe_sampler_state state; 745bf215546Sopenharmony_ci memset(&state, 0, sizeof(state)); 746bf215546Sopenharmony_ci state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 747bf215546Sopenharmony_ci state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 748bf215546Sopenharmony_ci state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 749bf215546Sopenharmony_ci state.normalized_coords = 1; 750bf215546Sopenharmony_ci 751bf215546Sopenharmony_ci return ctx->sampler_state = ctx->base.create_sampler_state(&ctx->base, &state); 752bf215546Sopenharmony_ci} 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_cistatic struct pipe_resource * 755bf215546Sopenharmony_ciresolve_stencil_to_temp(struct d3d12_context *ctx, 756bf215546Sopenharmony_ci const struct pipe_blit_info *info) 757bf215546Sopenharmony_ci{ 758bf215546Sopenharmony_ci struct pipe_context *pctx = &ctx->base; 759bf215546Sopenharmony_ci struct pipe_resource *tmp = create_tmp_resource(pctx->screen, info); 760bf215546Sopenharmony_ci if (!tmp) { 761bf215546Sopenharmony_ci debug_printf("D3D12: failed to create stencil-resolve temp-resource\n"); 762bf215546Sopenharmony_ci return NULL; 763bf215546Sopenharmony_ci } 764bf215546Sopenharmony_ci assert(tmp->nr_samples < 2); 765bf215546Sopenharmony_ci 766bf215546Sopenharmony_ci /* resolve stencil into tmp */ 767bf215546Sopenharmony_ci struct pipe_surface dst_tmpl; 768bf215546Sopenharmony_ci util_blitter_default_dst_texture(&dst_tmpl, tmp, 0, 0); 769bf215546Sopenharmony_ci dst_tmpl.format = tmp->format; 770bf215546Sopenharmony_ci struct pipe_surface *dst_surf = pctx->create_surface(pctx, tmp, &dst_tmpl); 771bf215546Sopenharmony_ci if (!dst_surf) { 772bf215546Sopenharmony_ci debug_printf("D3D12: failed to create stencil-resolve dst-surface\n"); 773bf215546Sopenharmony_ci return NULL; 774bf215546Sopenharmony_ci } 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci struct pipe_sampler_view src_templ, *src_view; 777bf215546Sopenharmony_ci util_blitter_default_src_texture(ctx->blitter, &src_templ, 778bf215546Sopenharmony_ci info->src.resource, info->src.level); 779bf215546Sopenharmony_ci src_templ.format = util_format_stencil_only(info->src.format); 780bf215546Sopenharmony_ci src_view = pctx->create_sampler_view(pctx, info->src.resource, &src_templ); 781bf215546Sopenharmony_ci 782bf215546Sopenharmony_ci void *sampler_state = get_sampler_state(ctx); 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci util_blit_save_state(ctx); 785bf215546Sopenharmony_ci pctx->set_sampler_views(pctx, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view); 786bf215546Sopenharmony_ci pctx->bind_sampler_states(pctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler_state); 787bf215546Sopenharmony_ci util_blitter_custom_shader(ctx->blitter, dst_surf, 788bf215546Sopenharmony_ci get_stencil_resolve_vs(ctx), 789bf215546Sopenharmony_ci get_stencil_resolve_fs(ctx, info->src.box.height == info->dst.box.height)); 790bf215546Sopenharmony_ci util_blitter_restore_textures(ctx->blitter); 791bf215546Sopenharmony_ci pipe_surface_reference(&dst_surf, NULL); 792bf215546Sopenharmony_ci pipe_sampler_view_reference(&src_view, NULL); 793bf215546Sopenharmony_ci return tmp; 794bf215546Sopenharmony_ci} 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_cistatic void 797bf215546Sopenharmony_ciblit_resolve_stencil(struct d3d12_context *ctx, 798bf215546Sopenharmony_ci const struct pipe_blit_info *info) 799bf215546Sopenharmony_ci{ 800bf215546Sopenharmony_ci assert(info->mask & PIPE_MASK_S); 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci if (D3D12_DEBUG_BLIT & d3d12_debug) 803bf215546Sopenharmony_ci debug_printf("D3D12 BLIT: blit_resolve_stencil\n"); 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci if (info->mask & PIPE_MASK_Z) { 806bf215546Sopenharmony_ci /* resolve depth into dst */ 807bf215546Sopenharmony_ci struct pipe_blit_info new_info = *info; 808bf215546Sopenharmony_ci new_info.mask = PIPE_MASK_Z; 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci if (resolve_supported(&new_info)) 811bf215546Sopenharmony_ci blit_resolve(ctx, &new_info); 812bf215546Sopenharmony_ci else 813bf215546Sopenharmony_ci util_blit(ctx, &new_info); 814bf215546Sopenharmony_ci } 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci struct pipe_resource *tmp = resolve_stencil_to_temp(ctx, info); 817bf215546Sopenharmony_ci 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci /* copy resolved stencil into dst */ 820bf215546Sopenharmony_ci struct d3d12_resource *dst = d3d12_resource(info->dst.resource); 821bf215546Sopenharmony_ci d3d12_transition_subresources_state(ctx, d3d12_resource(tmp), 822bf215546Sopenharmony_ci 0, 1, 0, 1, 0, 1, 823bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_COPY_SOURCE, 824bf215546Sopenharmony_ci D3D12_TRANSITION_FLAG_NONE); 825bf215546Sopenharmony_ci d3d12_transition_subresources_state(ctx, dst, 826bf215546Sopenharmony_ci 0, 1, 0, 1, 1, 1, 827bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_COPY_DEST, 828bf215546Sopenharmony_ci D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS); 829bf215546Sopenharmony_ci d3d12_apply_resource_states(ctx, false); 830bf215546Sopenharmony_ci 831bf215546Sopenharmony_ci struct d3d12_batch *batch = d3d12_current_batch(ctx); 832bf215546Sopenharmony_ci d3d12_batch_reference_resource(batch, d3d12_resource(tmp), false); 833bf215546Sopenharmony_ci d3d12_batch_reference_resource(batch, dst, true); 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci D3D12_BOX src_box; 836bf215546Sopenharmony_ci src_box.left = src_box.top = src_box.front = 0; 837bf215546Sopenharmony_ci src_box.right = tmp->width0; 838bf215546Sopenharmony_ci src_box.bottom = tmp->height0; 839bf215546Sopenharmony_ci src_box.back = tmp->depth0; 840bf215546Sopenharmony_ci 841bf215546Sopenharmony_ci D3D12_TEXTURE_COPY_LOCATION src_loc; 842bf215546Sopenharmony_ci src_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; 843bf215546Sopenharmony_ci src_loc.SubresourceIndex = 0; 844bf215546Sopenharmony_ci src_loc.pResource = d3d12_resource_resource(d3d12_resource(tmp)); 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci D3D12_TEXTURE_COPY_LOCATION dst_loc; 847bf215546Sopenharmony_ci dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; 848bf215546Sopenharmony_ci dst_loc.SubresourceIndex = 1; 849bf215546Sopenharmony_ci dst_loc.pResource = d3d12_resource_resource(dst); 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_ci ctx->cmdlist->CopyTextureRegion(&dst_loc, info->dst.box.x, 852bf215546Sopenharmony_ci info->dst.box.y, info->dst.box.z, 853bf215546Sopenharmony_ci &src_loc, &src_box); 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci pipe_resource_reference(&tmp, NULL); 856bf215546Sopenharmony_ci} 857bf215546Sopenharmony_ci 858bf215546Sopenharmony_cistatic bool 859bf215546Sopenharmony_cireplicate_stencil_supported(struct d3d12_context *ctx, 860bf215546Sopenharmony_ci const struct pipe_blit_info *info) 861bf215546Sopenharmony_ci{ 862bf215546Sopenharmony_ci if (!util_format_is_depth_or_stencil(info->src.format) || 863bf215546Sopenharmony_ci !(info->mask & PIPE_MASK_S)) 864bf215546Sopenharmony_ci return false; 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci if (info->mask & PIPE_MASK_Z) { 867bf215546Sopenharmony_ci struct pipe_blit_info new_info = *info; 868bf215546Sopenharmony_ci new_info.mask = PIPE_MASK_Z; 869bf215546Sopenharmony_ci if (!util_blitter_is_blit_supported(ctx->blitter, &new_info)) 870bf215546Sopenharmony_ci return false; 871bf215546Sopenharmony_ci } 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_ci return true; 874bf215546Sopenharmony_ci} 875bf215546Sopenharmony_ci 876bf215546Sopenharmony_cistatic void 877bf215546Sopenharmony_ciblit_replicate_stencil(struct d3d12_context *ctx, 878bf215546Sopenharmony_ci const struct pipe_blit_info *info) 879bf215546Sopenharmony_ci{ 880bf215546Sopenharmony_ci assert(info->mask & PIPE_MASK_S); 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci if (D3D12_DEBUG_BLIT & d3d12_debug) 883bf215546Sopenharmony_ci debug_printf("D3D12 BLIT: blit_replicate_stencil\n"); 884bf215546Sopenharmony_ci 885bf215546Sopenharmony_ci if (info->mask & PIPE_MASK_Z) { 886bf215546Sopenharmony_ci /* resolve depth into dst */ 887bf215546Sopenharmony_ci struct pipe_blit_info new_info = *info; 888bf215546Sopenharmony_ci new_info.mask = PIPE_MASK_Z; 889bf215546Sopenharmony_ci util_blit(ctx, &new_info); 890bf215546Sopenharmony_ci } 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci util_blit_save_state(ctx); 893bf215546Sopenharmony_ci util_blitter_stencil_fallback(ctx->blitter, info->dst.resource, 894bf215546Sopenharmony_ci info->dst.level, 895bf215546Sopenharmony_ci &info->dst.box, 896bf215546Sopenharmony_ci info->src.resource, 897bf215546Sopenharmony_ci info->src.level, 898bf215546Sopenharmony_ci &info->src.box, 899bf215546Sopenharmony_ci info->scissor_enable ? &info->scissor : NULL); 900bf215546Sopenharmony_ci} 901bf215546Sopenharmony_ci 902bf215546Sopenharmony_civoid 903bf215546Sopenharmony_cid3d12_blit(struct pipe_context *pctx, 904bf215546Sopenharmony_ci const struct pipe_blit_info *info) 905bf215546Sopenharmony_ci{ 906bf215546Sopenharmony_ci struct d3d12_context *ctx = d3d12_context(pctx); 907bf215546Sopenharmony_ci 908bf215546Sopenharmony_ci if (!info->render_condition_enable && ctx->current_predication) { 909bf215546Sopenharmony_ci if (D3D12_DEBUG_BLIT & d3d12_debug) 910bf215546Sopenharmony_ci debug_printf("D3D12 BLIT: Disable predication\n"); 911bf215546Sopenharmony_ci ctx->cmdlist->SetPredication(nullptr, 0, D3D12_PREDICATION_OP_EQUAL_ZERO); 912bf215546Sopenharmony_ci } 913bf215546Sopenharmony_ci 914bf215546Sopenharmony_ci if (D3D12_DEBUG_BLIT & d3d12_debug) { 915bf215546Sopenharmony_ci debug_printf("D3D12 BLIT: from %s@%d msaa:%d %dx%dx%d + %dx%dx%d\n", 916bf215546Sopenharmony_ci util_format_name(info->src.format), info->src.level, 917bf215546Sopenharmony_ci info->src.resource->nr_samples, 918bf215546Sopenharmony_ci info->src.box.x, info->src.box.y, info->src.box.z, 919bf215546Sopenharmony_ci info->src.box.width, info->src.box.height, info->src.box.depth); 920bf215546Sopenharmony_ci debug_printf(" to %s@%d msaa:%d %dx%dx%d + %dx%dx%d ", 921bf215546Sopenharmony_ci util_format_name(info->dst.format), info->dst.level, 922bf215546Sopenharmony_ci info->dst.resource->nr_samples, 923bf215546Sopenharmony_ci info->dst.box.x, info->dst.box.y, info->dst.box.z, 924bf215546Sopenharmony_ci info->dst.box.width, info->dst.box.height, info->dst.box.depth); 925bf215546Sopenharmony_ci debug_printf("| flags %s%s%s\n", 926bf215546Sopenharmony_ci info->render_condition_enable ? "cond " : "", 927bf215546Sopenharmony_ci info->scissor_enable ? "scissor " : "", 928bf215546Sopenharmony_ci info->alpha_blend ? "blend" : ""); 929bf215546Sopenharmony_ci } 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci if (is_same_resource(info)) 932bf215546Sopenharmony_ci blit_same_resource(ctx, info); 933bf215546Sopenharmony_ci else if (is_resolve(info)) { 934bf215546Sopenharmony_ci if (resolve_supported(info)) 935bf215546Sopenharmony_ci blit_resolve(ctx, info); 936bf215546Sopenharmony_ci else if (util_blitter_is_blit_supported(ctx->blitter, info)) 937bf215546Sopenharmony_ci util_blit(ctx, info); 938bf215546Sopenharmony_ci else if (resolve_stencil_supported(ctx, info)) 939bf215546Sopenharmony_ci blit_resolve_stencil(ctx, info); 940bf215546Sopenharmony_ci else 941bf215546Sopenharmony_ci debug_printf("D3D12: resolve unsupported %s -> %s\n", 942bf215546Sopenharmony_ci util_format_short_name(info->src.resource->format), 943bf215546Sopenharmony_ci util_format_short_name(info->dst.resource->format)); 944bf215546Sopenharmony_ci } else if (direct_copy_supported(d3d12_screen(pctx->screen), info, 945bf215546Sopenharmony_ci ctx->current_predication != nullptr)) 946bf215546Sopenharmony_ci d3d12_direct_copy(ctx, d3d12_resource(info->dst.resource), 947bf215546Sopenharmony_ci info->dst.level, &info->dst.box, 948bf215546Sopenharmony_ci d3d12_resource(info->src.resource), 949bf215546Sopenharmony_ci info->src.level, &info->src.box, info->mask); 950bf215546Sopenharmony_ci else if (util_blitter_is_blit_supported(ctx->blitter, info)) 951bf215546Sopenharmony_ci util_blit(ctx, info); 952bf215546Sopenharmony_ci else if (replicate_stencil_supported(ctx, info)) 953bf215546Sopenharmony_ci blit_replicate_stencil(ctx, info); 954bf215546Sopenharmony_ci else 955bf215546Sopenharmony_ci debug_printf("D3D12: blit unsupported %s -> %s\n", 956bf215546Sopenharmony_ci util_format_short_name(info->src.resource->format), 957bf215546Sopenharmony_ci util_format_short_name(info->dst.resource->format)); 958bf215546Sopenharmony_ci 959bf215546Sopenharmony_ci if (!info->render_condition_enable && ctx->current_predication) { 960bf215546Sopenharmony_ci d3d12_enable_predication(ctx); 961bf215546Sopenharmony_ci if (D3D12_DEBUG_BLIT & d3d12_debug) 962bf215546Sopenharmony_ci debug_printf("D3D12 BLIT: Re-enable predication\n"); 963bf215546Sopenharmony_ci } 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_ci} 966bf215546Sopenharmony_ci 967bf215546Sopenharmony_cistatic void 968bf215546Sopenharmony_cid3d12_resource_copy_region(struct pipe_context *pctx, 969bf215546Sopenharmony_ci struct pipe_resource *pdst, 970bf215546Sopenharmony_ci unsigned dst_level, 971bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned dstz, 972bf215546Sopenharmony_ci struct pipe_resource *psrc, 973bf215546Sopenharmony_ci unsigned src_level, 974bf215546Sopenharmony_ci const struct pipe_box *psrc_box) 975bf215546Sopenharmony_ci{ 976bf215546Sopenharmony_ci struct d3d12_context *ctx = d3d12_context(pctx); 977bf215546Sopenharmony_ci struct d3d12_resource *dst = d3d12_resource(pdst); 978bf215546Sopenharmony_ci struct d3d12_resource *src = d3d12_resource(psrc); 979bf215546Sopenharmony_ci struct pipe_resource *staging_res = NULL; 980bf215546Sopenharmony_ci const struct pipe_box *src_box = psrc_box; 981bf215546Sopenharmony_ci struct pipe_box staging_box, dst_box; 982bf215546Sopenharmony_ci 983bf215546Sopenharmony_ci if (D3D12_DEBUG_BLIT & d3d12_debug) { 984bf215546Sopenharmony_ci debug_printf("D3D12 COPY: from %s@%d msaa:%d mips:%d %dx%dx%d + %dx%dx%d\n", 985bf215546Sopenharmony_ci util_format_name(psrc->format), src_level, psrc->nr_samples, 986bf215546Sopenharmony_ci psrc->last_level, 987bf215546Sopenharmony_ci psrc_box->x, psrc_box->y, psrc_box->z, 988bf215546Sopenharmony_ci psrc_box->width, psrc_box->height, psrc_box->depth); 989bf215546Sopenharmony_ci debug_printf(" to %s@%d msaa:%d mips:%d %dx%dx%d\n", 990bf215546Sopenharmony_ci util_format_name(pdst->format), dst_level, psrc->nr_samples, 991bf215546Sopenharmony_ci psrc->last_level, dstx, dsty, dstz); 992bf215546Sopenharmony_ci } 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_ci /* Use an intermediate resource if copying from/to the same subresource */ 995bf215546Sopenharmony_ci if (d3d12_resource_resource(dst) == d3d12_resource_resource(src) && dst_level == src_level) { 996bf215546Sopenharmony_ci staging_res = create_staging_resource(ctx, src, src_level, psrc_box, &staging_box, PIPE_MASK_RGBAZS); 997bf215546Sopenharmony_ci src = d3d12_resource(staging_res); 998bf215546Sopenharmony_ci src_level = 0; 999bf215546Sopenharmony_ci src_box = &staging_box; 1000bf215546Sopenharmony_ci } 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci dst_box.x = dstx; 1003bf215546Sopenharmony_ci dst_box.y = dsty; 1004bf215546Sopenharmony_ci dst_box.z = dstz; 1005bf215546Sopenharmony_ci dst_box.width = psrc_box->width; 1006bf215546Sopenharmony_ci dst_box.height = psrc_box->height; 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci d3d12_direct_copy(ctx, dst, dst_level, &dst_box, 1009bf215546Sopenharmony_ci src, src_level, src_box, PIPE_MASK_RGBAZS); 1010bf215546Sopenharmony_ci 1011bf215546Sopenharmony_ci if (staging_res) 1012bf215546Sopenharmony_ci pipe_resource_reference(&staging_res, NULL); 1013bf215546Sopenharmony_ci} 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_civoid 1016bf215546Sopenharmony_cid3d12_context_blit_init(struct pipe_context *ctx) 1017bf215546Sopenharmony_ci{ 1018bf215546Sopenharmony_ci ctx->resource_copy_region = d3d12_resource_copy_region; 1019bf215546Sopenharmony_ci ctx->blit = d3d12_blit; 1020bf215546Sopenharmony_ci} 1021