diff options
author | Dave Airlie <[email protected]> | 2017-11-15 09:59:42 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2017-11-17 11:31:40 +1000 |
commit | a6b379284365e8adee780b691596d3a66de1ba93 (patch) | |
tree | c188e600e823ffc64a4f31006c648e50fda7505e /src/gallium/drivers/r600 | |
parent | 5689bb00229a422267ada6aef770dacc81e3319e (diff) |
r600: add core pieces of image support.
This adds the atoms and gallium api implementations,
along with support for compress/decompress paths for
shader images.
Tested-By: Gert Wollny <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 294 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_blit.c | 59 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_hw_context.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 45 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state_common.c | 30 |
6 files changed, 428 insertions, 3 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index c00114b6280..5a3a8514abb 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1678,6 +1678,104 @@ static void evergreen_emit_msaa_state(struct r600_context *rctx, int nr_samples, } } +static void evergreen_emit_image_state(struct r600_context *rctx, struct r600_atom *atom, + int immed_id_base, int res_id_base) +{ + struct r600_image_state *state = (struct r600_image_state *)atom; + struct pipe_framebuffer_state *fb_state = &rctx->framebuffer.state; + struct radeon_winsys_cs *cs = rctx->b.gfx.cs; + struct r600_texture *rtex; + struct r600_resource *resource; + uint32_t pkt_flags = 0; + int i; + + for (i = 0; i < R600_MAX_IMAGES; i++) { + struct r600_image_view *image = &state->views[i]; + unsigned reloc, immed_reloc; + int idx = i; + + idx += fb_state->nr_cbufs + (rctx->dual_src_blend ? 1 : 0); + if (!image->base.resource) + continue; + + resource = (struct r600_resource *)image->base.resource; + if (resource->b.b.target != PIPE_BUFFER) + rtex = (struct r600_texture *)image->base.resource; + else + rtex = NULL; + + reloc = radeon_add_to_buffer_list(&rctx->b, + &rctx->b.gfx, + resource, + RADEON_USAGE_READWRITE, + RADEON_PRIO_SHADER_RW_BUFFER); + + immed_reloc = radeon_add_to_buffer_list(&rctx->b, + &rctx->b.gfx, + resource->immed_buffer, + RADEON_USAGE_READWRITE, + RADEON_PRIO_SHADER_RW_BUFFER); + + radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + idx * 0x3C, 13); + + radeon_emit(cs, image->cb_color_base); /* R_028C60_CB_COLOR0_BASE */ + radeon_emit(cs, image->cb_color_pitch); /* R_028C64_CB_COLOR0_PITCH */ + radeon_emit(cs, image->cb_color_slice); /* R_028C68_CB_COLOR0_SLICE */ + radeon_emit(cs, image->cb_color_view); /* R_028C6C_CB_COLOR0_VIEW */ + radeon_emit(cs, image->cb_color_info); /* R_028C70_CB_COLOR0_INFO */ + radeon_emit(cs, image->cb_color_attrib); /* R_028C74_CB_COLOR0_ATTRIB */ + radeon_emit(cs, image->cb_color_dim); /* R_028C78_CB_COLOR0_DIM */ + radeon_emit(cs, rtex ? rtex->cmask.base_address_reg : image->cb_color_base); /* R_028C7C_CB_COLOR0_CMASK */ + radeon_emit(cs, rtex ? rtex->cmask.slice_tile_max : 0); /* R_028C80_CB_COLOR0_CMASK_SLICE */ + radeon_emit(cs, image->cb_color_fmask); /* R_028C84_CB_COLOR0_FMASK */ + radeon_emit(cs, image->cb_color_fmask_slice); /* R_028C88_CB_COLOR0_FMASK_SLICE */ + radeon_emit(cs, rtex ? rtex->color_clear_value[0] : 0); /* R_028C8C_CB_COLOR0_CLEAR_WORD0 */ + radeon_emit(cs, rtex ? rtex->color_clear_value[1] : 0); /* R_028C90_CB_COLOR0_CLEAR_WORD1 */ + + radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C60_CB_COLOR0_BASE */ + radeon_emit(cs, reloc); + + radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C74_CB_COLOR0_ATTRIB */ + radeon_emit(cs, reloc); + + radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C7C_CB_COLOR0_CMASK */ + radeon_emit(cs, reloc); + + radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C84_CB_COLOR0_FMASK */ + radeon_emit(cs, reloc); + + radeon_set_context_reg(cs, R_028B9C_CB_IMMED0_BASE + (idx * 4), resource->immed_buffer->gpu_address >> 8); + radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /**/ + radeon_emit(cs, immed_reloc); + + radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 8, 0) | pkt_flags); + radeon_emit(cs, (immed_id_base + i) * 8); + radeon_emit_array(cs, image->immed_resource_words, 8); + + radeon_emit(cs, PKT3(PKT3_NOP, 0, 0) | pkt_flags); + radeon_emit(cs, immed_reloc); + + radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 8, 0) | pkt_flags); + radeon_emit(cs, (res_id_base + i) * 8); + radeon_emit_array(cs, image->resource_words, 8); + + radeon_emit(cs, PKT3(PKT3_NOP, 0, 0) | pkt_flags); + radeon_emit(cs, reloc); + + if (!image->skip_mip_address_reloc) { + radeon_emit(cs, PKT3(PKT3_NOP, 0, 0) | pkt_flags); + radeon_emit(cs, reloc); + } + } +} + +static void evergreen_emit_fragment_image_state(struct r600_context *rctx, struct r600_atom *atom) +{ + evergreen_emit_image_state(rctx, atom, + R600_IMAGE_IMMED_RESOURCE_OFFSET, + R600_IMAGE_REAL_RESOURCE_OFFSET); +} + static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r600_atom *atom) { struct radeon_winsys_cs *cs = rctx->b.gfx.cs; @@ -1753,6 +1851,7 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r cb->cb_color_info | tex->cb_color_info); i++; } + i += util_bitcount(rctx->fragment_images.enabled_mask); for (; i < 8 ; i++) radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C, 0); for (; i < 12; i++) @@ -1867,9 +1966,9 @@ static void evergreen_emit_cb_misc_state(struct r600_context *rctx, struct r600_ struct r600_cb_misc_state *a = (struct r600_cb_misc_state*)atom; unsigned fb_colormask = (1ULL << ((unsigned)a->nr_cbufs * 4)) - 1; unsigned ps_colormask = (1ULL << ((unsigned)a->nr_ps_color_outputs * 4)) - 1; - + unsigned rat_colormask = ((1ULL << ((unsigned)a->nr_image_rats * 4)) - 1) << (a->nr_cbufs * 4); radeon_set_context_reg_seq(cs, R_028238_CB_TARGET_MASK, 2); - radeon_emit(cs, a->blend_colormask & fb_colormask); /* R_028238_CB_TARGET_MASK */ + radeon_emit(cs, (a->blend_colormask & fb_colormask) | rat_colormask); /* R_028238_CB_TARGET_MASK */ /* This must match the used export instructions exactly. * Other values may lead to undefined behavior and hangs. */ @@ -3772,6 +3871,195 @@ static void evergreen_set_hw_atomic_buffers(struct pipe_context *ctx, } } +static void evergreen_set_shader_images(struct pipe_context *ctx, + enum pipe_shader_type shader, unsigned start_slot, + unsigned count, + const struct pipe_image_view *images) +{ + struct r600_context *rctx = (struct r600_context *)ctx; + struct r600_screen *rscreen = (struct r600_screen *)ctx->screen; + int i; + struct r600_image_view *rview; + struct pipe_resource *image; + struct r600_resource *resource; + struct r600_tex_color_info color; + struct eg_buf_res_params buf_params; + struct eg_tex_res_params tex_params; + unsigned old_mask; + bool skip_reloc = false; + struct r600_image_state *istate = NULL; + int idx; + if (shader != PIPE_SHADER_FRAGMENT && count == 0) + return; + + istate = &rctx->fragment_images; + + assert (shader == PIPE_SHADER_FRAGMENT); + old_mask = istate->enabled_mask; + for (i = start_slot, idx = 0; i < start_slot + count; i++, idx++) { + unsigned res_type; + const struct pipe_image_view *iview; + rview = &istate->views[i]; + + if (!images || !images[idx].resource) { + pipe_resource_reference((struct pipe_resource **)&rview->base.resource, NULL); + istate->enabled_mask &= ~(1 << i); + continue; + } + + iview = &images[idx]; + image = iview->resource; + resource = (struct r600_resource *)image; + + r600_context_add_resource_size(ctx, image); + + rview->base = *iview; + rview->base.resource = NULL; + pipe_resource_reference((struct pipe_resource **)&rview->base.resource, image); + + if (!resource->immed_buffer) { + int immed_size = (rscreen->b.info.max_se * 256 * 64) * util_format_get_blocksize(iview->format); + + eg_resource_alloc_immed(&rscreen->b, resource, immed_size); + } + + bool is_buffer = image->target == PIPE_BUFFER; + struct r600_texture *rtex = (struct r600_texture *)image; + if (!is_buffer & rtex->db_compatible) + istate->compressed_depthtex_mask |= 1 << i; + else + istate->compressed_depthtex_mask &= ~(1 << i); + + if (!is_buffer && rtex->cmask.size) + istate->compressed_colortex_mask |= 1 << i; + else + istate->compressed_colortex_mask &= ~(1 << i); + if (!is_buffer) { + + evergreen_set_color_surface_common(rctx, rtex, + iview->u.tex.level, + iview->u.tex.first_layer, + iview->u.tex.last_layer, + iview->format, + &color); + color.dim = S_028C78_WIDTH_MAX(u_minify(image->width0, iview->u.tex.level) - 1) | + S_028C78_HEIGHT_MAX(u_minify(image->height0, iview->u.tex.level) - 1); + } else { + color.offset = 0; + color.view = 0; + evergreen_set_color_surface_buffer(rctx, resource, + iview->format, + iview->u.buf.offset, + iview->u.buf.size, + &color); + } + + switch (image->target) { + case PIPE_BUFFER: + res_type = V_028C70_BUFFER; + break; + case PIPE_TEXTURE_1D: + res_type = V_028C70_TEXTURE1D; + break; + case PIPE_TEXTURE_1D_ARRAY: + res_type = V_028C70_TEXTURE1DARRAY; + break; + case PIPE_TEXTURE_2D: + case PIPE_TEXTURE_RECT: + res_type = V_028C70_TEXTURE2D; + break; + case PIPE_TEXTURE_3D: + res_type = V_028C70_TEXTURE3D; + break; + case PIPE_TEXTURE_2D_ARRAY: + case PIPE_TEXTURE_CUBE: + case PIPE_TEXTURE_CUBE_ARRAY: + res_type = V_028C70_TEXTURE2DARRAY; + break; + default: + assert(0); + res_type = 0; + break; + } + + rview->cb_color_base = color.offset; + rview->cb_color_dim = color.dim; + rview->cb_color_info = color.info | + S_028C70_RAT(1) | + S_028C70_RESOURCE_TYPE(res_type); + rview->cb_color_pitch = color.pitch; + rview->cb_color_slice = color.slice; + rview->cb_color_view = color.view; + rview->cb_color_attrib = color.attrib; + rview->cb_color_fmask = color.fmask; + rview->cb_color_fmask_slice = color.fmask_slice; + + memset(&buf_params, 0, sizeof(buf_params)); + buf_params.pipe_format = iview->format; + buf_params.size = resource->immed_buffer->b.b.width0; + buf_params.swizzle[0] = PIPE_SWIZZLE_X; + buf_params.swizzle[1] = PIPE_SWIZZLE_Y; + buf_params.swizzle[2] = PIPE_SWIZZLE_Z; + buf_params.swizzle[3] = PIPE_SWIZZLE_W; + buf_params.uncached = 1; + evergreen_fill_buffer_resource_words(rctx, &resource->immed_buffer->b.b, + &buf_params, &skip_reloc, + rview->immed_resource_words); + + + if (image->target != PIPE_BUFFER) { + memset(&tex_params, 0, sizeof(tex_params)); + tex_params.pipe_format = iview->format; + tex_params.force_level = 0; + tex_params.width0 = image->width0; + tex_params.height0 = image->height0; + tex_params.first_level = iview->u.tex.level; + tex_params.last_level = iview->u.tex.level; + tex_params.first_layer = iview->u.tex.first_layer; + tex_params.last_layer = iview->u.tex.last_layer; + tex_params.target = image->target; + tex_params.swizzle[0] = PIPE_SWIZZLE_X; + tex_params.swizzle[1] = PIPE_SWIZZLE_Y; + tex_params.swizzle[2] = PIPE_SWIZZLE_Z; + tex_params.swizzle[3] = PIPE_SWIZZLE_W; + evergreen_fill_tex_resource_words(rctx, &resource->b.b, &tex_params, + &rview->skip_mip_address_reloc, + rview->resource_words); + + } else { + memset(&buf_params, 0, sizeof(buf_params)); + buf_params.pipe_format = iview->format; + buf_params.size = iview->u.buf.size; + buf_params.offset = iview->u.buf.offset; + buf_params.swizzle[0] = PIPE_SWIZZLE_X; + buf_params.swizzle[1] = PIPE_SWIZZLE_Y; + buf_params.swizzle[2] = PIPE_SWIZZLE_Z; + buf_params.swizzle[3] = PIPE_SWIZZLE_W; + evergreen_fill_buffer_resource_words(rctx, &resource->b.b, + &buf_params, + &rview->skip_mip_address_reloc, + rview->resource_words); + } + istate->enabled_mask |= (1 << i); + } + + istate->atom.num_dw = util_bitcount(istate->enabled_mask) * 46; + istate->dirty_buffer_constants = TRUE; + rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV; + rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB | + R600_CONTEXT_FLUSH_AND_INV_CB_META; + + if (old_mask != istate->enabled_mask) + r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom); + + if (rctx->cb_misc_state.nr_image_rats != util_bitcount(istate->enabled_mask)) { + rctx->cb_misc_state.nr_image_rats = util_bitcount(istate->enabled_mask); + r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom); + } + + r600_mark_atom_dirty(rctx, &istate->atom); +} + void evergreen_init_state_functions(struct r600_context *rctx) { unsigned id = 1; @@ -3790,6 +4078,7 @@ void evergreen_init_state_functions(struct r600_context *rctx) rctx->config_state.dyn_gpr_enabled = true; } r600_init_atom(rctx, &rctx->framebuffer.atom, id++, evergreen_emit_framebuffer_state, 0); + r600_init_atom(rctx, &rctx->fragment_images.atom, id++, evergreen_emit_fragment_image_state, 0); /* shader const */ r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_VERTEX].atom, id++, evergreen_emit_vs_constant_buffers, 0); r600_init_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_GEOMETRY].atom, id++, evergreen_emit_gs_constant_buffers, 0); @@ -3858,6 +4147,7 @@ void evergreen_init_state_functions(struct r600_context *rctx) rctx->b.b.set_min_samples = evergreen_set_min_samples; rctx->b.b.set_tess_state = evergreen_set_tess_state; rctx->b.b.set_hw_atomic_buffers = evergreen_set_hw_atomic_buffers; + rctx->b.b.set_shader_images = evergreen_set_shader_images; if (rctx->b.chip_class == EVERGREEN) rctx->b.b.get_sample_position = evergreen_get_sample_position; else diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 64f06e8bd4e..05d04f5399e 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -291,6 +291,40 @@ void r600_decompress_depth_textures(struct r600_context *rctx, } } +void r600_decompress_depth_images(struct r600_context *rctx, + struct r600_image_state *images) +{ + unsigned i; + unsigned depth_texture_mask = images->compressed_depthtex_mask; + + while (depth_texture_mask) { + struct r600_image_view *view; + struct r600_texture *tex; + + i = u_bit_scan(&depth_texture_mask); + + view = &images->views[i]; + assert(view); + + tex = (struct r600_texture *)view->base.resource; + assert(tex->db_compatible); + + if (r600_can_sample_zs(tex, false)) { + r600_blit_decompress_depth_in_place(rctx, tex, + false, + view->base.u.tex.level, + view->base.u.tex.level, + 0, util_max_layer(&tex->resource.b.b, view->base.u.tex.level)); + } else { + r600_blit_decompress_depth(&rctx->b.b, tex, NULL, + view->base.u.tex.level, + view->base.u.tex.level, + 0, util_max_layer(&tex->resource.b.b, view->base.u.tex.level), + 0, u_max_sample(&tex->resource.b.b)); + } + } +} + static void r600_blit_decompress_color(struct pipe_context *ctx, struct r600_texture *rtex, unsigned first_level, unsigned last_level, @@ -360,6 +394,31 @@ void r600_decompress_color_textures(struct r600_context *rctx, } } +void r600_decompress_color_images(struct r600_context *rctx, + struct r600_image_state *images) +{ + unsigned i; + unsigned mask = images->compressed_colortex_mask; + + while (mask) { + struct r600_image_view *view; + struct r600_texture *tex; + + i = u_bit_scan(&mask); + + view = &images->views[i]; + assert(view); + + tex = (struct r600_texture *)view->base.resource; + assert(tex->cmask.size); + + r600_blit_decompress_color(&rctx->b.b, tex, + view->base.u.tex.level, view->base.u.tex.level, + view->base.u.tex.first_layer, + view->base.u.tex.last_layer); + } +} + /* Helper for decompressing a portion of a color or depth resource before * blitting if any decompression is needed. * The driver doesn't decompress resources automatically while u_blitter is diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index a821c35f248..727ad9c9a3c 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -348,6 +348,8 @@ void r600_begin_new_cs(struct r600_context *ctx) r600_mark_atom_dirty(ctx, &ctx->db_misc_state.atom); r600_mark_atom_dirty(ctx, &ctx->db_state.atom); r600_mark_atom_dirty(ctx, &ctx->framebuffer.atom); + if (ctx->b.chip_class >= EVERGREEN) + r600_mark_atom_dirty(ctx, &ctx->fragment_images.atom); r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[R600_HW_STAGE_PS].atom); r600_mark_atom_dirty(ctx, &ctx->poly_offset_state.atom); r600_mark_atom_dirty(ctx, &ctx->vgt_state.atom); diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 4fbc82b43f2..ad7e499be21 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -38,7 +38,16 @@ #include "tgsi/tgsi_scan.h" -#define R600_NUM_ATOMS 52 +#define R600_NUM_ATOMS 53 + +#define R600_MAX_IMAGES 8 +/* + * ranges reserved for images on evergreen + * first set for the immediate buffers, + * second for the actual resources for RESQ. + */ +#define R600_IMAGE_IMMED_RESOURCE_OFFSET 160 +#define R600_IMAGE_REAL_RESOURCE_OFFSET 168 /* read caches */ #define R600_CONTEXT_INV_VERTEX_CACHE (R600_CONTEXT_PRIVATE_FLAG << 0) @@ -135,6 +144,7 @@ struct r600_cb_misc_state { unsigned blend_colormask; /* 8*4 bits for 8 RGBA colorbuffers */ unsigned nr_cbufs; unsigned nr_ps_color_outputs; + unsigned nr_image_rats; bool multiwrite; bool dual_src_blend; }; @@ -425,6 +435,33 @@ struct r600_atomic_buffer_state { struct pipe_shader_buffer buffer[EG_MAX_ATOMIC_BUFFERS]; }; +struct r600_image_view { + struct pipe_image_view base; + uint32_t cb_color_base; + uint32_t cb_color_pitch; + uint32_t cb_color_slice; + uint32_t cb_color_view; + uint32_t cb_color_info; + uint32_t cb_color_attrib; + uint32_t cb_color_dim; + uint32_t cb_color_fmask; + uint32_t cb_color_fmask_slice; + uint32_t immed_resource_words[8]; + uint32_t resource_words[8]; + bool skip_mip_address_reloc; + uint32_t buf_size; +}; + +struct r600_image_state { + struct r600_atom atom; + uint32_t enabled_mask; + uint32_t dirty_mask; + uint32_t compressed_depthtex_mask; + uint32_t compressed_colortex_mask; + boolean dirty_buffer_constants; + struct r600_image_view views[R600_MAX_IMAGES]; +}; + struct r600_context { struct r600_common_context b; struct r600_screen *screen; @@ -480,6 +517,8 @@ struct r600_context { struct r600_stencil_ref_state stencil_ref; struct r600_vgt_state vgt_state; struct r600_atomic_buffer_state atomic_buffer_state; + /* only have images on fragment shader */ + struct r600_image_state fragment_images; /* Shaders and shader resources. */ struct r600_cso_state vertex_fetch_shader; struct r600_shader_state hw_shader_stages[EG_NUM_HW_STAGES]; @@ -648,8 +687,12 @@ bool evergreen_adjust_gprs(struct r600_context *rctx); void r600_init_blit_functions(struct r600_context *rctx); void r600_decompress_depth_textures(struct r600_context *rctx, struct r600_samplerview_state *textures); +void r600_decompress_depth_images(struct r600_context *rctx, + struct r600_image_state *images); void r600_decompress_color_textures(struct r600_context *rctx, struct r600_samplerview_state *textures); +void r600_decompress_color_images(struct r600_context *rctx, + struct r600_image_state *images); void r600_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index c6efbb9852f..ccbcd6723ad 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -118,6 +118,7 @@ struct r600_shader { boolean uses_atomics; boolean uses_images; uint8_t atomic_base; + uint8_t rat_base; }; union r600_shader_key { diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 4ae18fc14c5..1bd0a7647b8 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -753,6 +753,26 @@ static int r600_get_hw_atomic_count(const struct pipe_context *ctx, return value; } +static void r600_update_compressed_colortex_mask_images(struct r600_image_state *images) +{ + uint32_t mask = images->enabled_mask; + + while (mask) { + unsigned i = u_bit_scan(&mask); + struct pipe_resource *res = images->views[i].base.resource; + + if (res && res->target != PIPE_BUFFER) { + struct r600_texture *rtex = (struct r600_texture *)res; + + if (rtex->cmask.size) { + images->compressed_colortex_mask |= 1 << i; + } else { + images->compressed_colortex_mask &= ~(1 << i); + } + } + } +} + /* Compute the key for the hw shader variant */ static inline void r600_shader_selector_key(const struct pipe_context *ctx, const struct r600_pipe_shader_selector *sel, @@ -1473,6 +1493,7 @@ static void r600_update_compressed_resource_state(struct r600_context *rctx) for (i = 0; i < PIPE_SHADER_TYPES; ++i) { r600_update_compressed_colortex_mask(&rctx->samplers[i].views); } + r600_update_compressed_colortex_mask_images(&rctx->fragment_images); } /* Decompress textures if needed. */ @@ -1485,6 +1506,15 @@ static void r600_update_compressed_resource_state(struct r600_context *rctx) r600_decompress_color_textures(rctx, views); } } + + { + struct r600_image_state *istate; + istate = &rctx->fragment_images; + if (istate->compressed_depthtex_mask) + r600_decompress_depth_images(rctx, istate); + if (istate->compressed_colortex_mask) + r600_decompress_color_images(rctx, istate); + } } #define SELECT_SHADER_OR_FAIL(x) do { \ |