static void si_check_render_feedback_textures(struct si_context *sctx, struct si_textures_info *textures) { uint32_t mask = textures->views.desc.enabled_mask; while (mask) { const struct pipe_sampler_view *view; struct r600_texture *tex; bool render_feedback = false; unsigned i = u_bit_scan(&mask); view = textures->views.views[i]; if(view->texture->target == PIPE_BUFFER) continue; tex = (struct r600_texture *)view->texture; if (!tex->dcc_offset) continue; for (unsigned j = 0; j < sctx->framebuffer.state.nr_cbufs; ++j) { struct r600_surface * surf; if (!sctx->framebuffer.state.cbufs[j]) continue; surf = (struct r600_surface*)sctx->framebuffer.state.cbufs[j]; if (tex == (struct r600_texture*)surf->base.texture && surf->base.u.tex.level >= view->u.tex.first_level && surf->base.u.tex.level <= view->u.tex.last_level && surf->base.u.tex.first_layer <= view->u.tex.last_layer && surf->base.u.tex.last_layer >= view->u.tex.first_layer) render_feedback = true; } if (render_feedback) { struct si_screen *screen = sctx->screen; r600_texture_disable_dcc(&screen->b, tex); } } }
static void si_set_shader_images(struct pipe_context *pipe, unsigned shader, unsigned start_slot, unsigned count, struct pipe_image_view *views) { struct si_context *ctx = (struct si_context *)pipe; struct si_screen *screen = ctx->screen; struct si_images_info *images = &ctx->images[shader]; unsigned i, slot; assert(shader < SI_NUM_SHADERS); if (!count) return; assert(start_slot + count <= SI_NUM_IMAGES); for (i = 0, slot = start_slot; i < count; ++i, ++slot) { struct r600_resource *res; if (!views || !views[i].resource) { si_disable_shader_image(images, slot); continue; } res = (struct r600_resource *)views[i].resource; util_copy_image_view(&images->views[slot], &views[i]); si_sampler_view_add_buffer(ctx, &res->b.b, RADEON_USAGE_READWRITE); if (res->b.b.target == PIPE_BUFFER) { si_make_buffer_descriptor(screen, res, views[i].format, views[i].u.buf.first_element, views[i].u.buf.last_element, images->desc.list + slot * 8); images->compressed_colortex_mask &= ~(1 << slot); } else { static const unsigned char swizzle[4] = { 0, 1, 2, 3 }; struct r600_texture *tex = (struct r600_texture *)res; unsigned level; unsigned width, height, depth; assert(!tex->is_depth); assert(tex->fmask.size == 0); if (tex->dcc_offset && views[i].access & PIPE_IMAGE_ACCESS_WRITE) r600_texture_disable_dcc(&screen->b, tex); if (is_compressed_colortex(tex)) { images->compressed_colortex_mask |= 1 << slot; } else { images->compressed_colortex_mask &= ~(1 << slot); } /* Always force the base level to the selected level. * * This is required for 3D textures, where otherwise * selecting a single slice for non-layered bindings * fails. It doesn't hurt the other targets. */ level = views[i].u.tex.level; width = u_minify(res->b.b.width0, level); height = u_minify(res->b.b.height0, level); depth = u_minify(res->b.b.depth0, level); si_make_texture_descriptor(screen, tex, false, res->b.b.target, views[i].format, swizzle, level, 0, 0, views[i].u.tex.first_layer, views[i].u.tex.last_layer, width, height, depth, images->desc.list + slot * 8, NULL); } images->desc.enabled_mask |= 1u << slot; images->desc.dirty_mask |= 1u << slot; } }