diff --git a/src/gallium/drivers/radeonsi/si_compute_blit.c b/src/gallium/drivers/radeonsi/si_compute_blit.c index d0ddef6e670..dce0c273920 100644 --- a/src/gallium/drivers/radeonsi/si_compute_blit.c +++ b/src/gallium/drivers/radeonsi/si_compute_blit.c @@ -1050,6 +1050,18 @@ bool si_compute_blit(struct si_context *sctx, const struct pipe_blit_info *info, unsigned max_dst_chan_size = util_format_get_max_channel_size(info->dst.format); unsigned max_src_chan_size = util_format_get_max_channel_size(info->src.format); + /* Reject blits with invalid parameters. */ + if (info->dst.box.width < 0 || info->dst.box.height < 0 || info->dst.box.depth < 0 || + info->src.box.depth < 0) { + assert(!"invalid box parameters"); /* this is reachable and prevents hangs */ + return true; + } + + /* Skip zero-area blits. */ + if (!info->dst.box.width || !info->dst.box.height || !info->dst.box.depth || + !info->src.box.width || !info->src.box.height || !info->src.box.depth) + return true; + /* MSAA image stores don't work on <= Gfx10.3. It's an issue with FMASK because * AMD_DEBUG=nofmask fixes them. EQAA image stores are also unimplemented. * MSAA image stores work fine on Gfx11 (it has neither FMASK nor EQAA). @@ -1083,27 +1095,9 @@ bool si_compute_blit(struct si_context *sctx, const struct pipe_blit_info *info, if (sctx->gfx_level < GFX11 && sctx->has_graphics && !testing) return false; - assert(info->src.box.depth >= 0); - if (sctx->gfx_level < GFX10 && !sctx->has_graphics && vi_dcc_enabled(sdst, info->dst.level)) si_texture_disable_dcc(sctx, sdst); - /* Shader images. */ - struct pipe_image_view image[2]; - image[0].resource = info->src.resource; - image[0].shader_access = image[0].access = PIPE_IMAGE_ACCESS_READ; - image[0].format = info->src.format; - image[0].u.tex.level = info->src.level; - image[0].u.tex.first_layer = 0; - image[0].u.tex.last_layer = util_max_layer(info->src.resource, info->src.level); - - image[1].resource = info->dst.resource; - image[1].shader_access = image[1].access = PIPE_IMAGE_ACCESS_WRITE; - image[1].format = info->dst.format; - image[1].u.tex.level = info->dst.level; - image[1].u.tex.first_layer = 0; - image[1].u.tex.last_layer = util_max_layer(info->dst.resource, info->dst.level); - unsigned width = info->dst.box.width; unsigned height = info->dst.box.height; unsigned depth = info->dst.box.depth; @@ -1326,6 +1320,22 @@ bool si_compute_blit(struct si_context *sctx, const struct pipe_blit_info *info, sctx->cs_user_data[2] = (info->src.box.z & 0xffff) | ((info->dst.box.z & 0xffff) << 16); sctx->cs_user_data[3] = (start_x & 0xff) | ((start_y & 0xff) << 8) | ((start_z & 0xff) << 16); + /* Shader images. */ + struct pipe_image_view image[2]; + image[0].resource = info->src.resource; + image[0].shader_access = image[0].access = PIPE_IMAGE_ACCESS_READ; + image[0].format = info->src.format; + image[0].u.tex.level = info->src.level; + image[0].u.tex.first_layer = 0; + image[0].u.tex.last_layer = util_max_layer(info->src.resource, info->src.level); + + image[1].resource = info->dst.resource; + image[1].shader_access = image[1].access = PIPE_IMAGE_ACCESS_WRITE; + image[1].format = info->dst.format; + image[1].u.tex.level = info->dst.level; + image[1].u.tex.first_layer = 0; + image[1].u.tex.last_layer = util_max_layer(info->dst.resource, info->dst.level); + si_launch_grid_internal_images(sctx, image, 2, &grid, shader, SI_OP_SYNC_BEFORE_AFTER | (info->render_condition_enable ? SI_OP_CS_RENDER_COND_ENABLE : 0)); diff --git a/src/gallium/drivers/radeonsi/si_shaderlib_nir.c b/src/gallium/drivers/radeonsi/si_shaderlib_nir.c index 10dc604323c..a4de5d31dd1 100644 --- a/src/gallium/drivers/radeonsi/si_shaderlib_nir.c +++ b/src/gallium/drivers/radeonsi/si_shaderlib_nir.c @@ -383,20 +383,15 @@ static nir_def *apply_blit_output_modifiers(nir_builder *b, nir_def *color, } /* The compute blit shader. - * - * Differences compared to u_blitter (the gfx blit): - * - u_blitter doesn't preserve NaNs, but the compute blit does - * - u_blitter has lower linear->SRGB precision because the CB block doesn't - * use FP32, but the compute blit does. - * - * Other than that, non-scaled blits are identical to u_blitter. * * Implementation details: * - Out-of-bounds dst coordinates are not clamped at all. The hw drops * out-of-bounds stores for us. * - Out-of-bounds src coordinates are clamped by emulating CLAMP_TO_EDGE using * the image_size NIR intrinsic. - * - X/Y flipping just does this in the shader: -threadIDs - 1 + * - X/Y flipping just does this in the shader: -threadIDs - 1, assuming the starting coordinates + * are 1 pixel after the bottom-right corner, e.g. x + width, matching the gallium behavior. + * - This list doesn't do it justice. */ void *si_create_blit_cs(struct si_context *sctx, const union si_compute_blit_shader_key *options) {