From 914d4967d723c58ec073eef677237798c2dc9751 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Wed, 2 Mar 2016 21:11:57 +0200 Subject: radeonsi: Do colorformat endian swap for PIPE_USAGE_STAGING MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is an old if statement (dated to 2011) that prevented doing endian swap for colorformat, in case the buffer is marked as PIPE_USAGE_STAGING. This is now wrong because st_ReadPixels() reads into a destination texture that is marked with PIPE_USAGE_STAGING. Therefore, even if the texture is rendered correctly to the monitor, when reading it back we get unswapped/wrong values. This patch makes the check_rgba() function in gl-1.0-readpixsanity piglit test pass in big-endian. Signed-off-by: Oded Gabbay Cc: "11.1 11.2" Reviewed-by: Marek Olšák --- src/gallium/drivers/radeonsi/si_state.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index b23b17ad77b..15732a6c254 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2250,11 +2250,7 @@ static void si_initialize_color_surface(struct si_context *sctx, } assert(format != V_028C70_COLOR_INVALID); swap = r600_translate_colorswap(surf->base.format); - if (rtex->resource.b.b.usage == PIPE_USAGE_STAGING) { - endian = V_028C70_ENDIAN_NONE; - } else { - endian = si_colorformat_endian_swap(format); - } + endian = si_colorformat_endian_swap(format); /* blend clamp should be set for all NORM/SRGB types */ if (ntype == V_028C70_NUMBER_UNORM || -- cgit v1.2.3 From 970b979da1639d57e89169f96cc0064db9dae43a Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 1 Mar 2016 21:50:25 +0100 Subject: gallium/radeon: eliminate fast color clear before sharing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Michel Dänzer Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeon/r600_texture.c | 16 ++++++++++++++++ src/gallium/drivers/radeonsi/si_blit.c | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 229fa5efa78..ec2f2454b1c 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -249,6 +249,17 @@ static void r600_texture_init_metadata(struct r600_texture *rtex, metadata->scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0; } +static void r600_eliminate_fast_color_clear(struct r600_common_screen *rscreen, + struct r600_texture *rtex) +{ + struct pipe_context *ctx = rscreen->aux_context; + + pipe_mutex_lock(rscreen->aux_context_lock); + ctx->flush_resource(ctx, &rtex->resource.b.b); + ctx->flush(ctx, NULL, 0); + pipe_mutex_unlock(rscreen->aux_context_lock); +} + static boolean r600_texture_get_handle(struct pipe_screen* screen, struct pipe_resource *resource, struct winsys_handle *whandle, @@ -271,6 +282,11 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen, res->external_usage = usage; if (resource->target != PIPE_BUFFER) { + if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH)) { + /* Eliminate fast clear (both CMASK and DCC) */ + r600_eliminate_fast_color_clear(rscreen, rtex); + } + r600_texture_init_metadata(rtex, &metadata); rscreen->ws->buffer_set_metadata(res->buf, &metadata); } diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 115877060ba..53c67055a5e 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -761,7 +761,7 @@ static void si_flush_resource(struct pipe_context *ctx, assert(res->target != PIPE_BUFFER); - if (!rtex->is_depth && rtex->cmask.size) { + if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_buffer)) { si_blit_decompress_color(ctx, rtex, 0, res->last_level, 0, util_max_layer(res, 0)); } -- cgit v1.2.3 From 60c08aa90bce4c8766a747c8517f7ff6987937f0 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 24 Feb 2016 22:04:47 +0100 Subject: gallium/radeon: disable CMASK on handle export if sharing doesn't allow it (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: remove the list of all contexts Reviewed-by: Michel Dänzer Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/r600/r600_state_common.c | 9 ++++++- src/gallium/drivers/radeon/r600_pipe_common.h | 8 +++++++ src/gallium/drivers/radeon/r600_texture.c | 34 +++++++++++++++++++++++++++ src/gallium/drivers/radeonsi/si_state_draw.c | 12 +++++++++- 4 files changed, 61 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index aa3a085c6d2..e3314bbf426 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -1672,7 +1672,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info struct radeon_winsys_cs *cs = rctx->b.gfx.cs; bool render_cond_bit = rctx->b.render_cond && !rctx->b.render_cond_force_off; uint64_t mask; - unsigned num_patches; + unsigned num_patches, dirty_fb_counter; if (!info.indirect && !info.count && (info.indexed || !info.count_from_stream_output)) { return; @@ -1688,6 +1688,13 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info rctx->b.dma.flush(rctx, RADEON_FLUSH_ASYNC, NULL); } + /* Re-emit the framebuffer state if needed. */ + dirty_fb_counter = p_atomic_read(&rctx->b.screen->dirty_fb_counter); + if (dirty_fb_counter != rctx->b.last_dirty_fb_counter) { + rctx->b.last_dirty_fb_counter = dirty_fb_counter; + r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom); + } + if (!r600_update_derived_state(rctx)) { /* useless to render because current rendering command * can't be achieved diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 3bbbfbbd528..7763ea30777 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -325,6 +325,13 @@ struct r600_common_screen { /* Performance counters. */ struct r600_perfcounters *perfcounters; + + /* If pipe_screen wants to re-emit the framebuffer state of all + * contexts, it should atomically increment this. Each context will + * compare this with its own last known value of the counter before + * drawing and re-emit the framebuffer state accordingly. + */ + unsigned dirty_fb_counter; }; /* This encapsulates a state or an operation which can emitted into the GPU @@ -392,6 +399,7 @@ struct r600_common_context { struct pipe_fence_handle *last_sdma_fence; unsigned initial_gfx_cs_size; unsigned gpu_reset_counter; + unsigned last_dirty_fb_counter; struct u_upload_mgr *uploader; struct u_suballocator *allocator_so_filled_size; diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index ec2f2454b1c..65b17a01dc3 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -249,6 +249,11 @@ static void r600_texture_init_metadata(struct r600_texture *rtex, metadata->scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0; } +static void r600_dirty_all_framebuffer_states(struct r600_common_screen *rscreen) +{ + p_atomic_inc(&rscreen->dirty_fb_counter); +} + static void r600_eliminate_fast_color_clear(struct r600_common_screen *rscreen, struct r600_texture *rtex) { @@ -260,6 +265,30 @@ static void r600_eliminate_fast_color_clear(struct r600_common_screen *rscreen, pipe_mutex_unlock(rscreen->aux_context_lock); } +static void r600_texture_disable_cmask(struct r600_common_screen *rscreen, + struct r600_texture *rtex) +{ + if (!rtex->cmask.size) + return; + + assert(rtex->resource.b.b.nr_samples <= 1); + + /* Disable CMASK. */ + memset(&rtex->cmask, 0, sizeof(rtex->cmask)); + rtex->cmask.base_address_reg = rtex->resource.gpu_address >> 8; + + if (rscreen->chip_class >= SI) + rtex->cb_color_info &= ~SI_S_028C70_FAST_CLEAR(1); + else + rtex->cb_color_info &= ~EG_S_028C70_FAST_CLEAR(1); + + if (rtex->cmask_buffer != &rtex->resource) + pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL); + + /* Notify all contexts about the change. */ + r600_dirty_all_framebuffer_states(rscreen); +} + static boolean r600_texture_get_handle(struct pipe_screen* screen, struct pipe_resource *resource, struct winsys_handle *whandle, @@ -285,6 +314,11 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen, if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH)) { /* Eliminate fast clear (both CMASK and DCC) */ r600_eliminate_fast_color_clear(rscreen, rtex); + + /* Disable CMASK if flush_resource isn't going + * to be called. + */ + r600_texture_disable_cmask(rscreen, rtex); } r600_texture_init_metadata(rtex, &metadata); diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 91ccd073267..5d094c71734 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -763,7 +763,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) struct si_context *sctx = (struct si_context *)ctx; struct si_state_rasterizer *rs = sctx->queued.named.rasterizer; struct pipe_index_buffer ib = {}; - unsigned mask; + unsigned mask, dirty_fb_counter; if (!info->count && !info->indirect && (info->indexed || !info->count_from_stream_output)) @@ -782,6 +782,16 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) return; } + /* Re-emit the framebuffer state if needed. */ + dirty_fb_counter = p_atomic_read(&sctx->b.screen->dirty_fb_counter); + if (dirty_fb_counter != sctx->b.last_dirty_fb_counter) { + sctx->b.last_dirty_fb_counter = dirty_fb_counter; + sctx->framebuffer.dirty_cbufs |= + ((1 << sctx->framebuffer.state.nr_cbufs) - 1); + sctx->framebuffer.dirty_zsbuf = true; + si_mark_atom_dirty(sctx, &sctx->framebuffer.atom); + } + si_decompress_textures(sctx); /* Set the rasterization primitive type. -- cgit v1.2.3 From b744ac9f44099e1b50d335dc9bdc0950ab7ec374 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 21 Feb 2016 22:49:38 +0100 Subject: radeonsi: allocate DCC in the same backing buffer as the texture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To allow sharing textures with DCC enabled. Reviewed-by: Michel Dänzer Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeon/r600_pipe_common.h | 2 +- src/gallium/drivers/radeon/r600_texture.c | 51 ++++++++++++--------------- src/gallium/drivers/radeonsi/cik_sdma.c | 2 +- src/gallium/drivers/radeonsi/si_blit.c | 8 ++--- src/gallium/drivers/radeonsi/si_descriptors.c | 8 +---- src/gallium/drivers/radeonsi/si_dma.c | 2 +- src/gallium/drivers/radeonsi/si_pipe.h | 1 - src/gallium/drivers/radeonsi/si_state.c | 21 +++++------ 8 files changed, 38 insertions(+), 57 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 7763ea30777..32213971370 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -222,7 +222,7 @@ struct r600_texture { struct r600_fmask_info fmask; struct r600_cmask_info cmask; struct r600_resource *cmask_buffer; - struct r600_resource *dcc_buffer; + unsigned dcc_offset; /* 0 = disabled */ unsigned cb_color_info; /* fast clear enable bit */ unsigned color_clear_value[2]; diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 65b17a01dc3..1fff33ef5b5 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -346,7 +346,6 @@ static void r600_texture_destroy(struct pipe_screen *screen, if (rtex->cmask_buffer != &rtex->resource) { pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL); } - pipe_resource_reference((struct pipe_resource**)&rtex->dcc_buffer, NULL); pb_reference(&resource->buf, NULL); FREE(rtex); } @@ -569,25 +568,6 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1); } -static void vi_texture_alloc_dcc_separate(struct r600_common_screen *rscreen, - struct r600_texture *rtex) -{ - if (rscreen->debug_flags & DBG_NO_DCC) - return; - - rtex->dcc_buffer = (struct r600_resource *) - r600_aligned_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM, - PIPE_USAGE_DEFAULT, rtex->surface.dcc_size, rtex->surface.dcc_alignment); - if (rtex->dcc_buffer == NULL) { - return; - } - - r600_screen_clear_buffer(rscreen, &rtex->dcc_buffer->b.b, 0, rtex->surface.dcc_size, - 0xFFFFFFFF, true); - - rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1); -} - static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen, struct r600_texture *rtex) { @@ -722,10 +702,10 @@ void r600_print_texture_info(struct r600_texture *rtex, FILE *f) rtex->htile_buffer->buf->alignment, rtex->htile.pitch, rtex->htile.height, rtex->htile.xalign, rtex->htile.yalign); - if (rtex->dcc_buffer) { - fprintf(f, " DCC: size=%u, alignment=%u\n", - rtex->dcc_buffer->b.b.width0, - rtex->dcc_buffer->buf->alignment); + if (rtex->dcc_offset) { + fprintf(f, " DCC: offset=%u, size=%"PRIu64", alignment=%"PRIu64"\n", + rtex->dcc_offset, rtex->surface.dcc_size, + rtex->surface.dcc_alignment); for (i = 0; i <= rtex->surface.last_level; i++) fprintf(f, " DCCLevel[%i]: offset=%"PRIu64"\n", i, rtex->surface.level[i].dcc_offset); @@ -823,8 +803,14 @@ r600_texture_create_object(struct pipe_screen *screen, return NULL; } } - if (rtex->surface.dcc_size) - vi_texture_alloc_dcc_separate(rscreen, rtex); + + if (!buf && rtex->surface.dcc_size && + !(rscreen->debug_flags & DBG_NO_DCC)) { + /* Reserve space for the DCC buffer. */ + rtex->dcc_offset = align(rtex->size, rtex->surface.dcc_alignment); + rtex->size = rtex->dcc_offset + rtex->surface.dcc_size; + rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1); + } } /* Now create the backing buffer. */ @@ -846,6 +832,12 @@ r600_texture_create_object(struct pipe_screen *screen, rtex->cmask.offset, rtex->cmask.size, 0xCCCCCCCC, true); } + if (rtex->dcc_offset) { + r600_screen_clear_buffer(rscreen, &rtex->resource.b.b, + rtex->dcc_offset, + rtex->surface.dcc_size, + 0xFFFFFFFF, true); + } /* Initialize the CMASK base register value. */ rtex->cmask.base_address_reg = @@ -1553,7 +1545,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx, continue; } - if (tex->dcc_buffer) { + if (tex->dcc_offset) { uint32_t reset_value; bool clear_words_needed; @@ -1562,8 +1554,9 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx, vi_get_fast_clear_parameters(fb->cbufs[i]->format, color, &reset_value, &clear_words_needed); - rctx->clear_buffer(&rctx->b, &tex->dcc_buffer->b.b, - 0, tex->surface.dcc_size, reset_value, true); + rctx->clear_buffer(&rctx->b, &tex->resource.b.b, + tex->dcc_offset, tex->surface.dcc_size, + reset_value, true); if (clear_words_needed) tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level; diff --git a/src/gallium/drivers/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c index 76913914b38..6eb62dcc890 100644 --- a/src/gallium/drivers/radeonsi/cik_sdma.c +++ b/src/gallium/drivers/radeonsi/cik_sdma.c @@ -243,7 +243,7 @@ void cik_sdma_copy(struct pipe_context *ctx, if (src->format != dst->format || rdst->surface.nsamples > 1 || rsrc->surface.nsamples > 1 || (rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) || - rdst->dcc_buffer || rsrc->dcc_buffer) { + rdst->dcc_offset || rsrc->dcc_offset) { goto fallback; } diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 53c67055a5e..60b9f7b6a70 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -330,7 +330,7 @@ void si_decompress_color_textures(struct si_context *sctx, assert(view); tex = (struct r600_texture *)view->texture; - assert(tex->cmask.size || tex->fmask.size || tex->dcc_buffer); + assert(tex->cmask.size || tex->fmask.size || tex->dcc_offset); si_blit_decompress_color(&sctx->b.b, tex, view->u.tex.first_level, view->u.tex.last_level, @@ -483,7 +483,7 @@ static void si_decompress_subresource(struct pipe_context *ctx, si_blit_decompress_depth_in_place(sctx, rtex, true, level, level, first_layer, last_layer); - } else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_buffer) { + } else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_offset) { si_blit_decompress_color(ctx, rtex, level, level, first_layer, last_layer); } @@ -712,7 +712,7 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx, dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D && !(dst->surface.flags & RADEON_SURF_SCANOUT) && (!dst->cmask.size || !dst->dirty_level_mask) && /* dst cannot be fast-cleared */ - !dst->dcc_buffer) { + !dst->dcc_offset) { si_blitter_begin(ctx, SI_COLOR_RESOLVE | (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND)); util_blitter_custom_resolve_color(sctx->blitter, @@ -761,7 +761,7 @@ static void si_flush_resource(struct pipe_context *ctx, assert(res->target != PIPE_BUFFER); - if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_buffer)) { + if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_offset)) { si_blit_decompress_color(ctx, rtex, 0, res->last_level, 0, util_max_layer(res, 0)); } diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 345f2bbc381..ba4a770079c 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -158,12 +158,6 @@ static void si_sampler_view_add_buffers(struct si_context *sctx, rview->resource, RADEON_USAGE_READ, r600_get_sampler_view_priority(rview->resource)); } - - if (rview->dcc_buffer && rview->dcc_buffer != rview->resource) { - radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, - rview->dcc_buffer, RADEON_USAGE_READ, - RADEON_PRIO_DCC); - } } static void si_sampler_views_begin_new_cs(struct si_context *sctx, @@ -263,7 +257,7 @@ static void si_set_sampler_views(struct pipe_context *ctx, samplers->depth_texture_mask &= ~(1 << slot); } if (rtex->cmask.size || rtex->fmask.size || - (rtex->dcc_buffer && rtex->dirty_level_mask)) { + (rtex->dcc_offset && rtex->dirty_level_mask)) { samplers->compressed_colortex_mask |= 1 << slot; } else { samplers->compressed_colortex_mask &= ~(1 << slot); diff --git a/src/gallium/drivers/radeonsi/si_dma.c b/src/gallium/drivers/radeonsi/si_dma.c index 240d96190a9..0efca193951 100644 --- a/src/gallium/drivers/radeonsi/si_dma.c +++ b/src/gallium/drivers/radeonsi/si_dma.c @@ -249,7 +249,7 @@ void si_dma_copy(struct pipe_context *ctx, (rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) || rdst->cmask.size || rdst->fmask.size || rsrc->cmask.size || rsrc->fmask.size || - rdst->dcc_buffer || rsrc->dcc_buffer) { + rdst->dcc_offset || rsrc->dcc_offset) { goto fallback; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index ef860a58b83..e6f92a31f96 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -121,7 +121,6 @@ struct si_sampler_view { struct pipe_sampler_view base; struct list_head list; struct r600_resource *resource; - struct r600_resource *dcc_buffer; /* [0..7] = image descriptor * [4..7] = buffer descriptor */ uint32_t state[8]; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 15732a6c254..08a6505b0b3 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2318,9 +2318,8 @@ static void si_initialize_color_surface(struct si_context *sctx, surf->cb_color_info = color_info; surf->cb_color_attrib = color_attrib; - if (sctx->b.chip_class >= VI && rtex->dcc_buffer) { + if (sctx->b.chip_class >= VI && rtex->dcc_offset) { unsigned max_uncompressed_block_size = 2; - uint64_t dcc_offset = rtex->surface.level[level].dcc_offset; if (rtex->surface.nsamples > 1) { if (rtex->surface.bpe == 1) @@ -2331,7 +2330,9 @@ static void si_initialize_color_surface(struct si_context *sctx, surf->cb_dcc_control = S_028C78_MAX_UNCOMPRESSED_BLOCK_SIZE(max_uncompressed_block_size) | S_028C78_INDEPENDENT_64B_BLOCKS(1); - surf->cb_dcc_base = (rtex->dcc_buffer->gpu_address + dcc_offset) >> 8; + surf->cb_dcc_base = (rtex->resource.gpu_address + + rtex->dcc_offset + + rtex->surface.level[level].dcc_offset) >> 8; } if (rtex->fmask.size) { @@ -2670,12 +2671,6 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom RADEON_PRIO_CMASK); } - if (tex->dcc_buffer && tex->dcc_buffer != &tex->resource) { - radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, - tex->dcc_buffer, RADEON_USAGE_READWRITE, - RADEON_PRIO_DCC); - } - radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, sctx->b.chip_class >= VI ? 14 : 13); radeon_emit(cs, cb->cb_color_base); /* R_028C60_CB_COLOR0_BASE */ @@ -3069,13 +3064,13 @@ si_create_sampler_view_custom(struct pipe_context *ctx, view->state[5] = (S_008F24_BASE_ARRAY(state->u.tex.first_layer) | S_008F24_LAST_ARRAY(last_layer)); - if (tmp->dcc_buffer) { - uint64_t dcc_offset = surflevel[base_level].dcc_offset; + if (tmp->dcc_offset) { unsigned swap = r600_translate_colorswap(pipe_format); view->state[6] = S_008F28_COMPRESSION_EN(1) | S_008F28_ALPHA_IS_ON_MSB(swap <= 1); - view->state[7] = (tmp->dcc_buffer->gpu_address + dcc_offset) >> 8; - view->dcc_buffer = tmp->dcc_buffer; + view->state[7] = (tmp->resource.gpu_address + + tmp->dcc_offset + + surflevel[base_level].dcc_offset) >> 8; } else { view->state[6] = 0; view->state[7] = 0; -- cgit v1.2.3 From 1e48ec7571cb36b4ee5660f8066c7905a3432969 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Wed, 21 Oct 2015 00:10:41 +0200 Subject: radeonsi: add DCC decompression (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is currently not needed but will be necessary when we have features that do not work with DCC enabled, such as image stores and sharing non-scanout surfaces. v2: Marek: rebase, remove decompression from si_flush_resource (not needed) Reviewed-by: Marek Olšák Reviewed-by: Michel Dänzer Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeonsi/si_blit.c | 28 +++++++++++++++++++--------- src/gallium/drivers/radeonsi/si_pipe.c | 2 ++ src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 1 + 4 files changed, 23 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 60b9f7b6a70..198f57d542f 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -271,18 +271,29 @@ void si_flush_depth_textures(struct si_context *sctx, static void si_blit_decompress_color(struct pipe_context *ctx, struct r600_texture *rtex, unsigned first_level, unsigned last_level, - unsigned first_layer, unsigned last_layer) + unsigned first_layer, unsigned last_layer, + bool need_dcc_decompress) { struct si_context *sctx = (struct si_context *)ctx; unsigned layer, level, checked_last_layer, max_layer; - if (!rtex->dirty_level_mask) + if (!rtex->dirty_level_mask && !need_dcc_decompress) return; for (level = first_level; level <= last_level; level++) { - if (!(rtex->dirty_level_mask & (1 << level))) + void* custom_blend; + + if (!(rtex->dirty_level_mask & (1 << level)) && !need_dcc_decompress) continue; + if (rtex->dcc_offset && need_dcc_decompress) { + custom_blend = sctx->custom_blend_dcc_decompress; + } else if (rtex->fmask.size) { + custom_blend = sctx->custom_blend_decompress; + } else { + custom_blend = sctx->custom_blend_fastclear; + } + /* The smaller the mipmap level, the less layers there are * as far as 3D textures are concerned. */ max_layer = util_max_layer(&rtex->resource.b.b, level); @@ -298,9 +309,7 @@ static void si_blit_decompress_color(struct pipe_context *ctx, cbsurf = ctx->create_surface(ctx, &rtex->resource.b.b, &surf_tmpl); si_blitter_begin(ctx, SI_DECOMPRESS); - util_blitter_custom_color(sctx->blitter, cbsurf, - rtex->fmask.size ? sctx->custom_blend_decompress : - sctx->custom_blend_fastclear); + util_blitter_custom_color(sctx->blitter, cbsurf, custom_blend); si_blitter_end(ctx); pipe_surface_reference(&cbsurf, NULL); @@ -334,7 +343,8 @@ void si_decompress_color_textures(struct si_context *sctx, si_blit_decompress_color(&sctx->b.b, tex, view->u.tex.first_level, view->u.tex.last_level, - 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level)); + 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level), + false); } } @@ -485,7 +495,7 @@ static void si_decompress_subresource(struct pipe_context *ctx, first_layer, last_layer); } else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_offset) { si_blit_decompress_color(ctx, rtex, level, level, - first_layer, last_layer); + first_layer, last_layer, false); } } @@ -763,7 +773,7 @@ static void si_flush_resource(struct pipe_context *ctx, if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_offset)) { si_blit_decompress_color(ctx, rtex, 0, res->last_level, - 0, util_max_layer(res, 0)); + 0, util_max_layer(res, 0), false); } } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 37fd4a25d59..b445f6f010f 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -68,6 +68,8 @@ static void si_destroy_context(struct pipe_context *context) sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_decompress); if (sctx->custom_blend_fastclear) sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_fastclear); + if (sctx->custom_blend_dcc_decompress) + sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_dcc_decompress); util_unreference_framebuffer_state(&sctx->framebuffer.state); if (sctx->blitter) diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index e6f92a31f96..4d45e8ca3f1 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -196,6 +196,7 @@ struct si_context { void *custom_blend_resolve; void *custom_blend_decompress; void *custom_blend_fastclear; + void *custom_blend_dcc_decompress; void *pstipple_sampler_state; struct si_screen *screen; struct pipe_fence_handle *last_gfx_fence; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 08a6505b0b3..c7be30a2967 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -3513,6 +3513,7 @@ void si_init_state_functions(struct si_context *sctx) sctx->custom_blend_resolve = si_create_blend_custom(sctx, V_028808_CB_RESOLVE); sctx->custom_blend_decompress = si_create_blend_custom(sctx, V_028808_CB_FMASK_DECOMPRESS); sctx->custom_blend_fastclear = si_create_blend_custom(sctx, V_028808_CB_ELIMINATE_FAST_CLEAR); + sctx->custom_blend_dcc_decompress = si_create_blend_custom(sctx, V_028808_CB_DCC_DECOMPRESS); sctx->b.b.set_clip_state = si_set_clip_state; sctx->b.b.set_scissor_states = si_set_scissor_states; -- cgit v1.2.3 From f18fc70d6f62719e4fae2f93f2d563894bc1437f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 24 Feb 2016 22:04:47 +0100 Subject: radeonsi: disable DCC on handle export if expecting write access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should be okay except that sampler views and images are not re-set. Reviewed-by: Michel Dänzer Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeon/r600_pipe_common.h | 3 +++ src/gallium/drivers/radeon/r600_texture.c | 33 +++++++++++++++++++++++++++ src/gallium/drivers/radeonsi/si_blit.c | 12 ++++++++++ 3 files changed, 48 insertions(+) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 32213971370..31ec24de9a2 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -476,6 +476,9 @@ struct r600_common_context { unsigned first_layer, unsigned last_layer, unsigned first_sample, unsigned last_sample); + void (*decompress_dcc)(struct pipe_context *ctx, + struct r600_texture *rtex); + /* Reallocate the buffer and update all resource bindings where * the buffer is bound, including all resource descriptors. */ void (*invalidate_buffer)(struct pipe_context *ctx, struct pipe_resource *buf); diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 1fff33ef5b5..b8c4c795b3c 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -289,6 +289,31 @@ static void r600_texture_disable_cmask(struct r600_common_screen *rscreen, r600_dirty_all_framebuffer_states(rscreen); } +static void r600_texture_disable_dcc(struct r600_common_screen *rscreen, + struct r600_texture *rtex) +{ + struct r600_common_context *rctx = + (struct r600_common_context *)rscreen->aux_context; + + if (!rtex->dcc_offset) + return; + + /* Decompress DCC. */ + pipe_mutex_lock(rscreen->aux_context_lock); + rctx->decompress_dcc(&rctx->b, rtex); + rctx->b.flush(&rctx->b, NULL, 0); + pipe_mutex_unlock(rscreen->aux_context_lock); + + /* Disable DCC. */ + rtex->dcc_offset = 0; + rtex->cb_color_info &= ~VI_S_028C70_DCC_ENABLE(1); + + /* Notify all contexts about the change. */ + r600_dirty_all_framebuffer_states(rscreen); + + /* TODO: re-set all sampler views and images, but how? */ +} + static boolean r600_texture_get_handle(struct pipe_screen* screen, struct pipe_resource *resource, struct winsys_handle *whandle, @@ -311,6 +336,13 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen, res->external_usage = usage; if (resource->target != PIPE_BUFFER) { + /* Since shader image stores don't support DCC on VI, + * disable it for external clients that want write + * access. + */ + if (usage & PIPE_HANDLE_USAGE_WRITE) + r600_texture_disable_dcc(rscreen, rtex); + if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH)) { /* Eliminate fast clear (both CMASK and DCC) */ r600_eliminate_fast_color_clear(rscreen, rtex); @@ -321,6 +353,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen, r600_texture_disable_cmask(rscreen, rtex); } + /* Set metadata. */ r600_texture_init_metadata(rtex, &metadata); rscreen->ws->buffer_set_metadata(res->buf, &metadata); } diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 198f57d542f..d9c4f8fca1d 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -777,6 +777,17 @@ static void si_flush_resource(struct pipe_context *ctx, } } +static void si_decompress_dcc(struct pipe_context *ctx, + struct r600_texture *rtex) +{ + if (!rtex->dcc_offset) + return; + + si_blit_decompress_color(ctx, rtex, 0, rtex->resource.b.b.last_level, + 0, util_max_layer(&rtex->resource.b.b, 0), + true); +} + static void si_pipe_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst, unsigned offset, unsigned size, @@ -846,4 +857,5 @@ void si_init_blit_functions(struct si_context *sctx) sctx->b.b.blit = si_blit; sctx->b.b.flush_resource = si_flush_resource; sctx->b.blit_decompress_depth = si_blit_decompress_depth; + sctx->b.decompress_dcc = si_decompress_dcc; } -- cgit v1.2.3 From 2dec5e09e19fd7aa40daaed92c3d6193a91faa92 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 26 Feb 2016 13:28:31 +0100 Subject: radeonsi: accept pipe_resource in si_sampler_view_add_buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and rename .._buffers -> .._buffer Based loosely on Nicolai's patch. This will make it easier to cherry-pick Nicolai's patches from his image support branch. Reviewed-by: Michel Dänzer Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeonsi/si_descriptors.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index ba4a770079c..d030baca531 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -150,14 +150,17 @@ static void si_release_sampler_views(struct si_sampler_views *views) si_release_descriptors(&views->desc); } -static void si_sampler_view_add_buffers(struct si_context *sctx, - struct si_sampler_view *rview) +static void si_sampler_view_add_buffer(struct si_context *sctx, + struct pipe_resource *resource) { - if (rview->resource) { - radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, - rview->resource, RADEON_USAGE_READ, - r600_get_sampler_view_priority(rview->resource)); - } + struct r600_resource *rres = (struct r600_resource*)resource; + + if (!resource) + return; + + radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, rres, + RADEON_USAGE_READ, + r600_get_sampler_view_priority(rres)); } static void si_sampler_views_begin_new_cs(struct si_context *sctx, @@ -168,10 +171,8 @@ static void si_sampler_views_begin_new_cs(struct si_context *sctx, /* Add buffers to the CS. */ while (mask) { int i = u_bit_scan64(&mask); - struct si_sampler_view *rview = - (struct si_sampler_view*)views->views[i]; - si_sampler_view_add_buffers(sctx, rview); + si_sampler_view_add_buffer(sctx, views->views[i]->texture); } if (!views->desc.buffer) @@ -192,7 +193,7 @@ static void si_set_sampler_view(struct si_context *sctx, (struct si_sampler_view*)view; struct r600_texture *rtex = (struct r600_texture*)view->texture; - si_sampler_view_add_buffers(sctx, rview); + si_sampler_view_add_buffer(sctx, view->texture); pipe_sampler_view_reference(&views->views[slot], view); memcpy(views->desc.list + slot * 16, rview->state, 8*4); -- cgit v1.2.3 From 2bf8ee34b8098ebeda82e21cc93919dc923531a1 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Sat, 6 Feb 2016 16:21:52 -0500 Subject: radeonsi: remove resource field from si_sampler_view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit view->resource is redundant with view->base.texture, so get rid of it. Reviewed-by: Marek Olšák Reviewed-by: Michel Dänzer --- src/gallium/drivers/radeonsi/si_descriptors.c | 2 +- src/gallium/drivers/radeonsi/si_pipe.h | 1 - src/gallium/drivers/radeonsi/si_state.c | 3 +-- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index d030baca531..37b9d68d4be 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -191,7 +191,7 @@ static void si_set_sampler_view(struct si_context *sctx, if (view) { struct si_sampler_view *rview = (struct si_sampler_view*)view; - struct r600_texture *rtex = (struct r600_texture*)view->texture; + struct r600_texture *rtex = (struct r600_texture *)view->texture; si_sampler_view_add_buffer(sctx, view->texture); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 4d45e8ca3f1..736307b17a1 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -120,7 +120,6 @@ struct si_blend_color { struct si_sampler_view { struct pipe_sampler_view base; struct list_head list; - struct r600_resource *resource; /* [0..7] = image descriptor * [4..7] = buffer descriptor */ uint32_t state[8]; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index c7be30a2967..cc19f029e6d 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2843,7 +2843,6 @@ si_create_sampler_view_custom(struct pipe_context *ctx, } pipe_resource_reference(&view->base.texture, texture); - view->resource = &tmp->resource; if (state->format == PIPE_FORMAT_X24S8_UINT || state->format == PIPE_FORMAT_S8X24_UINT || @@ -3135,7 +3134,7 @@ static void si_sampler_view_destroy(struct pipe_context *ctx, { struct si_sampler_view *view = (struct si_sampler_view *)state; - if (view->resource && view->resource->b.b.target == PIPE_BUFFER) + if (state->texture && state->texture->target == PIPE_BUFFER) LIST_DELINIT(&view->list); pipe_resource_reference(&state->texture, NULL); -- cgit v1.2.3 From 1197c69bdd4d2c99a2e05944af18488d7a3425be Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Sat, 6 Feb 2016 17:08:12 -0500 Subject: radeonsi: extract the buffer descriptor computation into its own function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow it to be re-used for shader image descriptors. Reviewed-by: Marek Olšák Reviewed-by: Michel Dänzer --- src/gallium/drivers/radeonsi/si_state.c | 73 ++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index cc19f029e6d..5d65791f844 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2792,6 +2792,48 @@ static void si_set_min_samples(struct pipe_context *ctx, unsigned min_samples) * Samplers */ +/** + * Build the sampler view descriptor for a buffer texture. + * @param state 256-bit descriptor; only the high 128 bits are filled in + */ +static void +si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf, + enum pipe_format format, + unsigned first_element, unsigned last_element, + uint32_t *state) +{ + const struct util_format_description *desc; + int first_non_void; + uint64_t va; + unsigned stride; + unsigned num_records; + unsigned num_format, data_format; + + desc = util_format_description(format); + first_non_void = util_format_get_first_non_void_channel(format); + stride = desc->block.bits / 8; + va = buf->gpu_address + first_element * stride; + num_format = si_translate_buffer_numformat(&screen->b.b, desc, first_non_void); + data_format = si_translate_buffer_dataformat(&screen->b.b, desc, first_non_void); + + num_records = last_element + 1 - first_element; + num_records = MIN2(num_records, buf->b.b.width0 / stride); + + if (screen->b.chip_class >= VI) + num_records *= stride; + + state[4] = va; + state[5] = S_008F04_BASE_ADDRESS_HI(va >> 32) | + S_008F04_STRIDE(stride); + state[6] = num_records; + state[7] = S_008F0C_DST_SEL_X(si_map_swizzle(desc->swizzle[0])) | + S_008F0C_DST_SEL_Y(si_map_swizzle(desc->swizzle[1])) | + S_008F0C_DST_SEL_Z(si_map_swizzle(desc->swizzle[2])) | + S_008F0C_DST_SEL_W(si_map_swizzle(desc->swizzle[3])) | + S_008F0C_NUM_FORMAT(num_format) | + S_008F0C_DATA_FORMAT(data_format); +} + /** * Create a sampler view. * @@ -2852,31 +2894,12 @@ si_create_sampler_view_custom(struct pipe_context *ctx, /* Buffer resource. */ if (texture->target == PIPE_BUFFER) { - unsigned stride, num_records; - - desc = util_format_description(state->format); - first_non_void = util_format_get_first_non_void_channel(state->format); - stride = desc->block.bits / 8; - va = tmp->resource.gpu_address + state->u.buf.first_element*stride; - format = si_translate_buffer_dataformat(ctx->screen, desc, first_non_void); - num_format = si_translate_buffer_numformat(ctx->screen, desc, first_non_void); - - num_records = state->u.buf.last_element + 1 - state->u.buf.first_element; - num_records = MIN2(num_records, texture->width0 / stride); - - if (sctx->b.chip_class >= VI) - num_records *= stride; - - view->state[4] = va; - view->state[5] = S_008F04_BASE_ADDRESS_HI(va >> 32) | - S_008F04_STRIDE(stride); - view->state[6] = num_records; - view->state[7] = S_008F0C_DST_SEL_X(si_map_swizzle(desc->swizzle[0])) | - S_008F0C_DST_SEL_Y(si_map_swizzle(desc->swizzle[1])) | - S_008F0C_DST_SEL_Z(si_map_swizzle(desc->swizzle[2])) | - S_008F0C_DST_SEL_W(si_map_swizzle(desc->swizzle[3])) | - S_008F0C_NUM_FORMAT(num_format) | - S_008F0C_DATA_FORMAT(format); + si_make_buffer_descriptor(sctx->screen, + (struct r600_resource *)texture, + state->format, + state->u.buf.first_element, + state->u.buf.last_element, + view->state); LIST_ADDTAIL(&view->list, &sctx->b.texture_buffers); return &view->base; -- cgit v1.2.3 From ff7e9412be9d1f5fdfedefb179483cc43b276c89 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Sat, 6 Feb 2016 17:34:04 -0500 Subject: radeonsi: extract the texture descriptor computation into its own function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow this code to be re-used for shader images. Reviewed-by: Marek Olšák Reviewed-by: Michel Dänzer --- src/gallium/drivers/radeonsi/si_state.c | 350 +++++++++++++++++--------------- 1 file changed, 186 insertions(+), 164 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 5d65791f844..8190913df8a 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2835,85 +2835,31 @@ si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf, } /** - * Create a sampler view. - * - * @param ctx context - * @param texture texture - * @param state sampler view template - * @param width0 width0 override (for compressed textures as int) - * @param height0 height0 override (for compressed textures as int) - * @param force_level set the base address to the level (for compressed textures) + * Build the sampler view descriptor for a texture. */ -struct pipe_sampler_view * -si_create_sampler_view_custom(struct pipe_context *ctx, - struct pipe_resource *texture, - const struct pipe_sampler_view *state, - unsigned width0, unsigned height0, - unsigned force_level) -{ - struct si_context *sctx = (struct si_context*)ctx; - struct si_sampler_view *view = CALLOC_STRUCT(si_sampler_view); - struct r600_texture *tmp = (struct r600_texture*)texture; +static void +si_make_texture_descriptor(struct si_screen *screen, + struct r600_texture *tex, + enum pipe_texture_target target, + enum pipe_format pipe_format, + const unsigned char state_swizzle[4], + unsigned base_level, unsigned first_level, unsigned last_level, + unsigned first_layer, unsigned last_layer, + unsigned width, unsigned height, unsigned depth, + uint32_t *state, + uint32_t *fmask_state) +{ + struct pipe_resource *res = &tex->resource.b.b; + const struct radeon_surf_level *surflevel = tex->surface.level; const struct util_format_description *desc; - unsigned format, num_format, base_level, first_level, last_level; - uint32_t pitch = 0; - unsigned char state_swizzle[4], swizzle[4]; - unsigned height, depth, width; - enum pipe_format pipe_format = state->format; - struct radeon_surf_level *surflevel; + unsigned char swizzle[4]; int first_non_void; + unsigned num_format, data_format; + uint32_t pitch; uint64_t va; - unsigned last_layer = state->u.tex.last_layer; - - if (!view) - return NULL; - - /* initialize base object */ - view->base = *state; - view->base.texture = NULL; - view->base.reference.count = 1; - view->base.context = ctx; - - /* NULL resource, obey swizzle (only ZERO and ONE make sense). */ - if (!texture) { - view->state[3] = S_008F1C_DST_SEL_X(si_map_swizzle(state->swizzle_r)) | - S_008F1C_DST_SEL_Y(si_map_swizzle(state->swizzle_g)) | - S_008F1C_DST_SEL_Z(si_map_swizzle(state->swizzle_b)) | - S_008F1C_DST_SEL_W(si_map_swizzle(state->swizzle_a)) | - S_008F1C_TYPE(V_008F1C_SQ_RSRC_IMG_1D); - return &view->base; - } - - pipe_resource_reference(&view->base.texture, texture); - - if (state->format == PIPE_FORMAT_X24S8_UINT || - state->format == PIPE_FORMAT_S8X24_UINT || - state->format == PIPE_FORMAT_X32_S8X24_UINT || - state->format == PIPE_FORMAT_S8_UINT) - view->is_stencil_sampler = true; - - /* Buffer resource. */ - if (texture->target == PIPE_BUFFER) { - si_make_buffer_descriptor(sctx->screen, - (struct r600_resource *)texture, - state->format, - state->u.buf.first_element, - state->u.buf.last_element, - view->state); - - LIST_ADDTAIL(&view->list, &sctx->b.texture_buffers); - return &view->base; - } - - state_swizzle[0] = state->swizzle_r; - state_swizzle[1] = state->swizzle_g; - state_swizzle[2] = state->swizzle_b; - state_swizzle[3] = state->swizzle_a; - - surflevel = tmp->surface.level; /* Texturing with separate depth and stencil. */ - if (tmp->is_depth && !tmp->is_flushing_texture) { + if (tex->is_depth && !tex->is_flushing_texture) { switch (pipe_format) { case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: pipe_format = PIPE_FORMAT_Z32_FLOAT; @@ -2927,7 +2873,7 @@ si_create_sampler_view_custom(struct pipe_context *ctx, case PIPE_FORMAT_S8X24_UINT: case PIPE_FORMAT_X32_S8X24_UINT: pipe_format = PIPE_FORMAT_S8_UINT; - surflevel = tmp->surface.stencil_level; + surflevel = tex->surface.stencil_level; break; default:; } @@ -3021,89 +2967,63 @@ si_create_sampler_view_custom(struct pipe_context *ctx, } } - format = si_translate_texformat(ctx->screen, pipe_format, desc, first_non_void); - if (format == ~0) { - format = 0; - } - - base_level = 0; - first_level = state->u.tex.first_level; - last_level = state->u.tex.last_level; - width = width0; - height = height0; - depth = texture->depth0; - - if (force_level) { - assert(force_level == first_level && - force_level == last_level); - base_level = force_level; - first_level = 0; - last_level = 0; - width = u_minify(width, force_level); - height = u_minify(height, force_level); - depth = u_minify(depth, force_level); + data_format = si_translate_texformat(&screen->b.b, pipe_format, desc, first_non_void); + if (data_format == ~0) { + data_format = 0; } - pitch = surflevel[base_level].nblk_x * util_format_get_blockwidth(pipe_format); - - if (texture->target == PIPE_TEXTURE_1D_ARRAY) { + if (res->target == PIPE_TEXTURE_1D_ARRAY) { height = 1; - depth = texture->array_size; - } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) { - depth = texture->array_size; - } else if (texture->target == PIPE_TEXTURE_CUBE_ARRAY) - depth = texture->array_size / 6; - - /* This is not needed if state trackers set last_layer correctly. */ - if (state->target == PIPE_TEXTURE_1D || - state->target == PIPE_TEXTURE_2D || - state->target == PIPE_TEXTURE_RECT || - state->target == PIPE_TEXTURE_CUBE) - last_layer = state->u.tex.first_layer; + depth = res->array_size; + } else if (res->target == PIPE_TEXTURE_2D_ARRAY) { + depth = res->array_size; + } else if (res->target == PIPE_TEXTURE_CUBE_ARRAY) + depth = res->array_size / 6; - va = tmp->resource.gpu_address + surflevel[base_level].offset; - - view->state[0] = va >> 8; - view->state[1] = (S_008F14_BASE_ADDRESS_HI(va >> 40) | - S_008F14_DATA_FORMAT(format) | - S_008F14_NUM_FORMAT(num_format)); - view->state[2] = (S_008F18_WIDTH(width - 1) | - S_008F18_HEIGHT(height - 1)); - view->state[3] = (S_008F1C_DST_SEL_X(si_map_swizzle(swizzle[0])) | - S_008F1C_DST_SEL_Y(si_map_swizzle(swizzle[1])) | - S_008F1C_DST_SEL_Z(si_map_swizzle(swizzle[2])) | - S_008F1C_DST_SEL_W(si_map_swizzle(swizzle[3])) | - S_008F1C_BASE_LEVEL(texture->nr_samples > 1 ? - 0 : first_level) | - S_008F1C_LAST_LEVEL(texture->nr_samples > 1 ? - util_logbase2(texture->nr_samples) : - last_level) | - S_008F1C_TILING_INDEX(si_tile_mode_index(tmp, base_level, false)) | - S_008F1C_POW2_PAD(texture->last_level > 0) | - S_008F1C_TYPE(si_tex_dim(texture->target, state->target, - texture->nr_samples))); - view->state[4] = (S_008F20_DEPTH(depth - 1) | S_008F20_PITCH(pitch - 1)); - view->state[5] = (S_008F24_BASE_ARRAY(state->u.tex.first_layer) | - S_008F24_LAST_ARRAY(last_layer)); - - if (tmp->dcc_offset) { + pitch = surflevel[base_level].nblk_x * util_format_get_blockwidth(pipe_format); + va = tex->resource.gpu_address + surflevel[base_level].offset; + + state[0] = va >> 8; + state[1] = (S_008F14_BASE_ADDRESS_HI(va >> 40) | + S_008F14_DATA_FORMAT(data_format) | + S_008F14_NUM_FORMAT(num_format)); + state[2] = (S_008F18_WIDTH(width - 1) | + S_008F18_HEIGHT(height - 1)); + state[3] = (S_008F1C_DST_SEL_X(si_map_swizzle(swizzle[0])) | + S_008F1C_DST_SEL_Y(si_map_swizzle(swizzle[1])) | + S_008F1C_DST_SEL_Z(si_map_swizzle(swizzle[2])) | + S_008F1C_DST_SEL_W(si_map_swizzle(swizzle[3])) | + S_008F1C_BASE_LEVEL(res->nr_samples > 1 ? + 0 : first_level) | + S_008F1C_LAST_LEVEL(res->nr_samples > 1 ? + util_logbase2(res->nr_samples) : + last_level) | + S_008F1C_TILING_INDEX(si_tile_mode_index(tex, base_level, false)) | + S_008F1C_POW2_PAD(res->last_level > 0) | + S_008F1C_TYPE(si_tex_dim(res->target, target, res->nr_samples))); + state[4] = (S_008F20_DEPTH(depth - 1) | S_008F20_PITCH(pitch - 1)); + state[5] = (S_008F24_BASE_ARRAY(first_layer) | + S_008F24_LAST_ARRAY(last_layer)); + + if (tex->dcc_offset) { unsigned swap = r600_translate_colorswap(pipe_format); - view->state[6] = S_008F28_COMPRESSION_EN(1) | S_008F28_ALPHA_IS_ON_MSB(swap <= 1); - view->state[7] = (tmp->resource.gpu_address + - tmp->dcc_offset + - surflevel[base_level].dcc_offset) >> 8; + state[6] = S_008F28_COMPRESSION_EN(1) | S_008F28_ALPHA_IS_ON_MSB(swap <= 1); + state[7] = (tex->resource.gpu_address + + tex->dcc_offset + + surflevel[base_level].dcc_offset) >> 8; } else { - view->state[6] = 0; - view->state[7] = 0; + state[6] = 0; + state[7] = 0; } /* Initialize the sampler view for FMASK. */ - if (tmp->fmask.size) { - uint64_t va = tmp->resource.gpu_address + tmp->fmask.offset; + if (tex->fmask.size) { uint32_t fmask_format; - switch (texture->nr_samples) { + va = tex->resource.gpu_address + tex->fmask.offset; + + switch (res->nr_samples) { case 2: fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2; break; @@ -3118,27 +3038,129 @@ si_create_sampler_view_custom(struct pipe_context *ctx, fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID; } - view->fmask_state[0] = va >> 8; - view->fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | - S_008F14_DATA_FORMAT(fmask_format) | - S_008F14_NUM_FORMAT(V_008F14_IMG_NUM_FORMAT_UINT); - view->fmask_state[2] = S_008F18_WIDTH(width - 1) | - S_008F18_HEIGHT(height - 1); - view->fmask_state[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) | - S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | - S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | - S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) | - S_008F1C_TILING_INDEX(tmp->fmask.tile_mode_index) | - S_008F1C_TYPE(si_tex_dim(texture->target, - state->target, 0)); - view->fmask_state[4] = S_008F20_DEPTH(depth - 1) | - S_008F20_PITCH(tmp->fmask.pitch_in_pixels - 1); - view->fmask_state[5] = S_008F24_BASE_ARRAY(state->u.tex.first_layer) | - S_008F24_LAST_ARRAY(last_layer); - view->fmask_state[6] = 0; - view->fmask_state[7] = 0; + fmask_state[0] = va >> 8; + fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | + S_008F14_DATA_FORMAT(fmask_format) | + S_008F14_NUM_FORMAT(V_008F14_IMG_NUM_FORMAT_UINT); + fmask_state[2] = S_008F18_WIDTH(width - 1) | + S_008F18_HEIGHT(height - 1); + fmask_state[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) | + S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | + S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | + S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) | + S_008F1C_TILING_INDEX(tex->fmask.tile_mode_index) | + S_008F1C_TYPE(si_tex_dim(res->target, target, 0)); + fmask_state[4] = S_008F20_DEPTH(depth - 1) | + S_008F20_PITCH(tex->fmask.pitch_in_pixels - 1); + fmask_state[5] = S_008F24_BASE_ARRAY(first_layer) | + S_008F24_LAST_ARRAY(last_layer); + fmask_state[6] = 0; + fmask_state[7] = 0; + } +} + +/** + * Create a sampler view. + * + * @param ctx context + * @param texture texture + * @param state sampler view template + * @param width0 width0 override (for compressed textures as int) + * @param height0 height0 override (for compressed textures as int) + * @param force_level set the base address to the level (for compressed textures) + */ +struct pipe_sampler_view * +si_create_sampler_view_custom(struct pipe_context *ctx, + struct pipe_resource *texture, + const struct pipe_sampler_view *state, + unsigned width0, unsigned height0, + unsigned force_level) +{ + struct si_context *sctx = (struct si_context*)ctx; + struct si_sampler_view *view = CALLOC_STRUCT(si_sampler_view); + struct r600_texture *tmp = (struct r600_texture*)texture; + unsigned base_level, first_level, last_level; + unsigned char state_swizzle[4]; + unsigned height, depth, width; + unsigned last_layer = state->u.tex.last_layer; + + if (!view) + return NULL; + + /* initialize base object */ + view->base = *state; + view->base.texture = NULL; + view->base.reference.count = 1; + view->base.context = ctx; + + /* NULL resource, obey swizzle (only ZERO and ONE make sense). */ + if (!texture) { + view->state[3] = S_008F1C_DST_SEL_X(si_map_swizzle(state->swizzle_r)) | + S_008F1C_DST_SEL_Y(si_map_swizzle(state->swizzle_g)) | + S_008F1C_DST_SEL_Z(si_map_swizzle(state->swizzle_b)) | + S_008F1C_DST_SEL_W(si_map_swizzle(state->swizzle_a)) | + S_008F1C_TYPE(V_008F1C_SQ_RSRC_IMG_1D); + return &view->base; + } + + pipe_resource_reference(&view->base.texture, texture); + + if (state->format == PIPE_FORMAT_X24S8_UINT || + state->format == PIPE_FORMAT_S8X24_UINT || + state->format == PIPE_FORMAT_X32_S8X24_UINT || + state->format == PIPE_FORMAT_S8_UINT) + view->is_stencil_sampler = true; + + /* Buffer resource. */ + if (texture->target == PIPE_BUFFER) { + si_make_buffer_descriptor(sctx->screen, + (struct r600_resource *)texture, + state->format, + state->u.buf.first_element, + state->u.buf.last_element, + view->state); + + LIST_ADDTAIL(&view->list, &sctx->b.texture_buffers); + return &view->base; + } + + state_swizzle[0] = state->swizzle_r; + state_swizzle[1] = state->swizzle_g; + state_swizzle[2] = state->swizzle_b; + state_swizzle[3] = state->swizzle_a; + + base_level = 0; + first_level = state->u.tex.first_level; + last_level = state->u.tex.last_level; + width = width0; + height = height0; + depth = texture->depth0; + + if (force_level) { + assert(force_level == first_level && + force_level == last_level); + base_level = force_level; + first_level = 0; + last_level = 0; + width = u_minify(width, force_level); + height = u_minify(height, force_level); + depth = u_minify(depth, force_level); } + /* This is not needed if state trackers set last_layer correctly. */ + if (state->target == PIPE_TEXTURE_1D || + state->target == PIPE_TEXTURE_2D || + state->target == PIPE_TEXTURE_RECT || + state->target == PIPE_TEXTURE_CUBE) + last_layer = state->u.tex.first_layer; + + si_make_texture_descriptor(sctx->screen, tmp, state->target, + state->format, state_swizzle, + base_level, first_level, last_level, + state->u.tex.first_layer, last_layer, + width, height, depth, + view->state, view->fmask_state); + return &view->base; } -- cgit v1.2.3 From ec74deeb2466689a0eca52f290d5f9e44af6a97b Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Thu, 25 Feb 2016 22:32:26 +0100 Subject: radeonsi: set amdgpu metadata before exporting a texture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Michel Dänzer Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/r600/r600_pipe.c | 2 +- src/gallium/drivers/radeon/r600_pipe_common.h | 6 +++ src/gallium/drivers/radeon/r600_texture.c | 4 ++ src/gallium/drivers/radeonsi/si_pipe.c | 4 +- src/gallium/drivers/radeonsi/si_state.c | 63 +++++++++++++++++++++++++++ src/gallium/drivers/radeonsi/si_state.h | 1 + 6 files changed, 78 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 5a6ce71414c..7d256dbe006 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -439,7 +439,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) return PIPE_ENDIAN_LITTLE; case PIPE_CAP_VENDOR_ID: - return 0x1002; + return ATI_VENDOR_ID; case PIPE_CAP_DEVICE_ID: return rscreen->b.info.pci_id; case PIPE_CAP_ACCELERATED: diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 31ec24de9a2..d20069ef0c9 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -43,6 +43,8 @@ #include "util/u_suballoc.h" #include "util/u_transfer.h" +#define ATI_VENDOR_ID 0x1002 + #define R600_RESOURCE_FLAG_TRANSFER (PIPE_RESOURCE_FLAG_DRV_PRIV << 0) #define R600_RESOURCE_FLAG_FLUSHED_DEPTH (PIPE_RESOURCE_FLAG_DRV_PRIV << 1) #define R600_RESOURCE_FLAG_FORCE_TILING (PIPE_RESOURCE_FLAG_DRV_PRIV << 2) @@ -332,6 +334,10 @@ struct r600_common_screen { * drawing and re-emit the framebuffer state accordingly. */ unsigned dirty_fb_counter; + + void (*query_opaque_metadata)(struct r600_common_screen *rscreen, + struct r600_texture *rtex, + struct radeon_bo_metadata *md); }; /* This encapsulates a state or an operation which can emitted into the GPU diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index b8c4c795b3c..1a8822ca54b 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -355,6 +355,10 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen, /* Set metadata. */ r600_texture_init_metadata(rtex, &metadata); + if (rscreen->query_opaque_metadata) + rscreen->query_opaque_metadata(rscreen, rtex, + &metadata); + rscreen->ws->buffer_set_metadata(res->buf, &metadata); } } else { diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index b445f6f010f..58e7f3acd67 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -420,7 +420,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) return PIPE_ENDIAN_LITTLE; case PIPE_CAP_VENDOR_ID: - return 0x1002; + return ATI_VENDOR_ID; case PIPE_CAP_DEVICE_ID: return sscreen->b.info.pci_id; case PIPE_CAP_ACCELERATED: @@ -613,6 +613,8 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws) sscreen->b.b.is_format_supported = si_is_format_supported; sscreen->b.b.resource_create = r600_resource_create_common; + si_init_screen_state_functions(sscreen); + if (!r600_common_screen_init(&sscreen->b, ws) || !si_init_gs_info(sscreen) || !si_init_shader_cache(sscreen)) { diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 8190913df8a..f823af188c7 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -34,6 +34,7 @@ #include "util/u_format_s3tc.h" #include "util/u_memory.h" #include "util/u_pstipple.h" +#include "util/u_resource.h" /* Initialize an external atom (owned by ../radeon). */ static void @@ -3600,6 +3601,68 @@ void si_init_state_functions(struct si_context *sctx) si_init_config(sctx); } +static void si_query_opaque_metadata(struct r600_common_screen *rscreen, + struct r600_texture *rtex, + struct radeon_bo_metadata *md) +{ + struct si_screen *sscreen = (struct si_screen*)rscreen; + struct pipe_resource *res = &rtex->resource.b.b; + static const unsigned char swizzle[] = { + PIPE_SWIZZLE_RED, + PIPE_SWIZZLE_GREEN, + PIPE_SWIZZLE_BLUE, + PIPE_SWIZZLE_ALPHA + }; + uint32_t desc[8], i; + bool is_array = util_resource_is_array_texture(res); + + /* DRM 2.x.x doesn't support this. */ + if (rscreen->info.drm_major != 3) + return; + + assert(rtex->fmask.size == 0); + + /* Metadata image format format version 1: + * [0] = 1 (metadata format identifier) + * [1] = (VENDOR_ID << 16) | PCI_ID + * [2:9] = image descriptor for the whole resource + * [2] is always 0, because the base address is cleared + * [9] is the DCC offset bits [39:8] from the beginning of + * the buffer + * [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level + */ + + md->metadata[0] = 1; /* metadata image format version 1 */ + + /* TILE_MODE_INDEX is ambiguous without a PCI ID. */ + md->metadata[1] = (ATI_VENDOR_ID << 16) | rscreen->info.pci_id; + + si_make_texture_descriptor(sscreen, rtex, res->target, res->format, + swizzle, 0, 0, res->last_level, 0, + is_array ? res->array_size - 1 : 0, + res->width0, res->height0, res->depth0, + desc, NULL); + + /* Clear the base address and set the relative DCC offset. */ + desc[0] = 0; + desc[1] &= C_008F14_BASE_ADDRESS_HI; + desc[7] = rtex->dcc_offset >> 8; + + /* Dwords [2:9] contain the image descriptor. */ + memcpy(&md->metadata[2], desc, sizeof(desc)); + + /* Dwords [10:..] contain the mipmap level offsets. */ + for (i = 0; i <= res->last_level; i++) + md->metadata[10+i] = rtex->surface.level[i].offset >> 8; + + md->size_metadata = (11 + res->last_level) * 4; +} + +void si_init_screen_state_functions(struct si_screen *sscreen) +{ + sscreen->b.query_opaque_metadata = si_query_opaque_metadata; +} + static void si_write_harvested_raster_configs(struct si_context *sctx, struct si_pm4_state *pm4, diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 40792cbc1d5..fb16d0f2953 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -263,6 +263,7 @@ boolean si_is_format_supported(struct pipe_screen *screen, unsigned sample_count, unsigned usage); void si_init_state_functions(struct si_context *sctx); +void si_init_screen_state_functions(struct si_screen *sscreen); unsigned cik_bank_wh(unsigned bankwh); unsigned cik_db_pipe_config(struct si_screen *sscreen, unsigned tile_mode); unsigned cik_macro_tile_aspect(unsigned macro_tile_aspect); -- cgit v1.2.3 From dcb2b7782317cf06c1c98472c9a34d2c9dfffae7 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 29 Feb 2016 20:22:37 +0100 Subject: gallium: add CAPs returning PCI device location Reviewed-by: Brian Paul --- src/gallium/docs/source/screen.rst | 4 ++++ src/gallium/drivers/freedreno/freedreno_screen.c | 4 ++++ src/gallium/drivers/i915/i915_screen.c | 4 ++++ src/gallium/drivers/ilo/ilo_screen.c | 4 ++++ src/gallium/drivers/llvmpipe/lp_screen.c | 4 ++++ src/gallium/drivers/nouveau/nv30/nv30_screen.c | 4 ++++ src/gallium/drivers/nouveau/nv50/nv50_screen.c | 4 ++++ src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 4 ++++ src/gallium/drivers/r300/r300_screen.c | 8 ++++++++ src/gallium/drivers/r600/r600_pipe.c | 8 ++++++++ src/gallium/drivers/radeonsi/si_pipe.c | 8 ++++++++ src/gallium/drivers/softpipe/sp_screen.c | 4 ++++ src/gallium/drivers/svga/svga_screen.c | 4 ++++ src/gallium/drivers/vc4/vc4_screen.c | 4 ++++ src/gallium/drivers/virgl/virgl_screen.c | 4 ++++ src/gallium/include/pipe/p_defines.h | 4 ++++ 16 files changed, 76 insertions(+) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index b5d691f4f7e..46ec3815412 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -319,6 +319,10 @@ The integer capabilities: adjusted appropriately. * ``PIPE_CAP_QUERY_BUFFER_OBJECT``: Driver supports context::get_query_result_resource callback. +* ``PIPE_CAP_PCI_GROUP``: Return the PCI segment group number. +* ``PIPE_CAP_PCI_BUS``: Return the PCI bus number. +* ``PIPE_CAP_PCI_DEVICE``: Return the PCI device number. +* ``PIPE_CAP_PCI_FUNCTION``: Return the PCI function number. .. _pipe_capf: diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 1565a1da38d..d47cb07f10b 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -166,6 +166,10 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_COMPUTE: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; case PIPE_CAP_SM3: diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 8d010f9dc8c..f4aa310ecdc 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -265,6 +265,10 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY: case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c index ef9da6b8315..548d215c718 100644 --- a/src/gallium/drivers/ilo/ilo_screen.c +++ b/src/gallium/drivers/ilo/ilo_screen.c @@ -493,6 +493,10 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_BUFFER_OBJECT: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 2c66bf46332..2529b546564 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -315,6 +315,10 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_BUFFER_OBJECT: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; } /* should only get here on unhandled cases */ diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index 5be7a3dab76..b105c6aeb80 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -188,6 +188,10 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_BUFFER_OBJECT: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 0bd5de91d1f..28e0ed3c225 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -232,6 +232,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_BUFFER_OBJECT: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 37620ea8ba6..114d868e919 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -225,6 +225,10 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY: case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 7fad7ad6a43..1c3bb64f0e4 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -259,6 +259,14 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) return r300screen->info.vram_size >> 20; case PIPE_CAP_UMA: return 0; + case PIPE_CAP_PCI_GROUP: + return r300screen->info.pci_domain; + case PIPE_CAP_PCI_BUS: + return r300screen->info.pci_bus; + case PIPE_CAP_PCI_DEVICE: + return r300screen->info.pci_dev; + case PIPE_CAP_PCI_FUNCTION: + return r300screen->info.pci_func; } return 0; } diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 7d256dbe006..7018088d204 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -450,6 +450,14 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) return 0; case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: return rscreen->b.chip_class >= R700; + case PIPE_CAP_PCI_GROUP: + return rscreen->b.info.pci_domain; + case PIPE_CAP_PCI_BUS: + return rscreen->b.info.pci_bus; + case PIPE_CAP_PCI_DEVICE: + return rscreen->b.info.pci_dev; + case PIPE_CAP_PCI_FUNCTION: + return rscreen->b.info.pci_func; } return 0; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 58e7f3acd67..8b50a49cba0 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -429,6 +429,14 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) return sscreen->b.info.vram_size >> 20; case PIPE_CAP_UMA: return 0; + case PIPE_CAP_PCI_GROUP: + return sscreen->b.info.pci_domain; + case PIPE_CAP_PCI_BUS: + return sscreen->b.info.pci_bus; + case PIPE_CAP_PCI_DEVICE: + return sscreen->b.info.pci_dev; + case PIPE_CAP_PCI_FUNCTION: + return sscreen->b.info.pci_func; } return 0; } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 097ffe6f920..bfd3598fc57 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -266,6 +266,10 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_BUFFER_OBJECT: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; } /* should only get here on unhandled cases */ diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index feb5103a3f6..bcc512041f7 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -360,6 +360,10 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_STRING_MARKER: case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: return 64; diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c index a4b3efcfda3..92d910ba6a5 100644 --- a/src/gallium/drivers/vc4/vc4_screen.c +++ b/src/gallium/drivers/vc4/vc4_screen.c @@ -203,6 +203,10 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: case PIPE_CAP_QUERY_BUFFER_OBJECT: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; /* Stream output. */ diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index d3f4e259cad..8126bdec40c 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -235,6 +235,10 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: case PIPE_CAP_STRING_MARKER: case PIPE_CAP_QUERY_MEMORY_INFO: + case PIPE_CAP_PCI_GROUP: + case PIPE_CAP_PCI_BUS: + case PIPE_CAP_PCI_DEVICE: + case PIPE_CAP_PCI_FUNCTION: return 0; case PIPE_CAP_VENDOR_ID: return 0x1af4; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index c9149bea309..a490b3b98ea 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -669,6 +669,10 @@ enum pipe_cap PIPE_CAP_SURFACE_REINTERPRET_BLOCKS, PIPE_CAP_QUERY_BUFFER_OBJECT, PIPE_CAP_QUERY_MEMORY_INFO, + PIPE_CAP_PCI_GROUP, + PIPE_CAP_PCI_BUS, + PIPE_CAP_PCI_DEVICE, + PIPE_CAP_PCI_FUNCTION, }; #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0) -- cgit v1.2.3 From da68a9b21501f4dbff6789362aec40f5221425c9 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Sun, 7 Feb 2016 22:27:17 -0500 Subject: radeonsi: move si_decompress_textures to si_blit.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since it is all about calling into blitter functions, it makes more sense here. This change also reduces the size of the interfaces between .c files. Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Marek Olšák --- src/gallium/drivers/radeonsi/si_blit.c | 26 ++++++++++++++++++++++---- src/gallium/drivers/radeonsi/si_pipe.h | 5 +---- src/gallium/drivers/radeonsi/si_state_draw.c | 15 --------------- 3 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index d9c4f8fca1d..e17343fd3d3 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -241,8 +241,9 @@ static void si_blit_decompress_depth_in_place(struct si_context *sctx, si_mark_atom_dirty(sctx, &sctx->db_render_state); } -void si_flush_depth_textures(struct si_context *sctx, - struct si_textures_info *textures) +static void +si_flush_depth_textures(struct si_context *sctx, + struct si_textures_info *textures) { unsigned i; unsigned mask = textures->depth_texture_mask; @@ -323,8 +324,9 @@ static void si_blit_decompress_color(struct pipe_context *ctx, } } -void si_decompress_color_textures(struct si_context *sctx, - struct si_textures_info *textures) +static void +si_decompress_color_textures(struct si_context *sctx, + struct si_textures_info *textures) { unsigned i; unsigned mask = textures->compressed_colortex_mask; @@ -348,6 +350,22 @@ void si_decompress_color_textures(struct si_context *sctx, } } +void si_decompress_textures(struct si_context *sctx) +{ + if (sctx->blitter->running) + return; + + /* Flush depth textures which need to be flushed. */ + for (int i = 0; i < SI_NUM_SHADERS; i++) { + if (sctx->samplers[i].depth_texture_mask) { + si_flush_depth_textures(sctx, &sctx->samplers[i]); + } + if (sctx->samplers[i].compressed_colortex_mask) { + si_decompress_color_textures(sctx, &sctx->samplers[i]); + } + } +} + static void si_clear(struct pipe_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 736307b17a1..0fef5f72098 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -333,10 +333,7 @@ void cik_sdma_copy(struct pipe_context *ctx, /* si_blit.c */ void si_init_blit_functions(struct si_context *sctx); -void si_flush_depth_textures(struct si_context *sctx, - struct si_textures_info *textures); -void si_decompress_color_textures(struct si_context *sctx, - struct si_textures_info *textures); +void si_decompress_textures(struct si_context *sctx); void si_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 5d094c71734..84b850a2992 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -33,21 +33,6 @@ #include "util/u_upload_mgr.h" #include "util/u_prim.h" -static void si_decompress_textures(struct si_context *sctx) -{ - if (!sctx->blitter->running) { - /* Flush depth textures which need to be flushed. */ - for (int i = 0; i < SI_NUM_SHADERS; i++) { - if (sctx->samplers[i].depth_texture_mask) { - si_flush_depth_textures(sctx, &sctx->samplers[i]); - } - if (sctx->samplers[i].compressed_colortex_mask) { - si_decompress_color_textures(sctx, &sctx->samplers[i]); - } - } - } -} - static unsigned si_conv_pipe_prim(unsigned mode) { static const unsigned prim_conv[] = { -- cgit v1.2.3 From 59c5508b9ab357c47aa07dfec6d74fec9d0843aa Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Wed, 9 Mar 2016 15:42:31 -0500 Subject: radeonsi: update compressed_colortex_masks when a cmask is created or disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Marek Olšák --- src/gallium/drivers/radeonsi/si_blit.c | 9 ++++++ src/gallium/drivers/radeonsi/si_descriptors.c | 43 +++++++++++++++++++++++++-- src/gallium/drivers/radeonsi/si_state.h | 1 + 3 files changed, 51 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index e17343fd3d3..f9a6de48f6b 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -352,9 +352,18 @@ si_decompress_color_textures(struct si_context *sctx, void si_decompress_textures(struct si_context *sctx) { + unsigned compressed_colortex_counter; + if (sctx->blitter->running) return; + /* Update the compressed_colortex_mask if necessary. */ + compressed_colortex_counter = p_atomic_read(&sctx->screen->b.compressed_colortex_counter); + if (compressed_colortex_counter != sctx->b.last_compressed_colortex_counter) { + sctx->b.last_compressed_colortex_counter = compressed_colortex_counter; + si_update_compressed_colortex_masks(sctx); + } + /* Flush depth textures which need to be flushed. */ for (int i = 0; i < SI_NUM_SHADERS; i++) { if (sctx->samplers[i].depth_texture_mask) { diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 37b9d68d4be..9aa48772975 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -224,6 +224,12 @@ static void si_set_sampler_view(struct si_context *sctx, views->desc.list_dirty = true; } +static bool is_compressed_colortex(struct r600_texture *rtex) +{ + return rtex->cmask.size || rtex->fmask.size || + (rtex->dcc_offset && rtex->dirty_level_mask); +} + static void si_set_sampler_views(struct pipe_context *ctx, unsigned shader, unsigned start, unsigned count, @@ -257,8 +263,7 @@ static void si_set_sampler_views(struct pipe_context *ctx, } else { samplers->depth_texture_mask &= ~(1 << slot); } - if (rtex->cmask.size || rtex->fmask.size || - (rtex->dcc_offset && rtex->dirty_level_mask)) { + if (is_compressed_colortex(rtex)) { samplers->compressed_colortex_mask |= 1 << slot; } else { samplers->compressed_colortex_mask &= ~(1 << slot); @@ -270,6 +275,27 @@ static void si_set_sampler_views(struct pipe_context *ctx, } } +static void +si_samplers_update_compressed_colortex_mask(struct si_textures_info *samplers) +{ + uint64_t mask = samplers->views.desc.enabled_mask; + + while (mask) { + int i = u_bit_scan64(&mask); + struct pipe_resource *res = samplers->views.views[i]->texture; + + if (res && res->target != PIPE_BUFFER) { + struct r600_texture *rtex = (struct r600_texture *)res; + + if (is_compressed_colortex(rtex)) { + samplers->compressed_colortex_mask |= 1 << i; + } else { + samplers->compressed_colortex_mask &= ~(1 << i); + } + } + } +} + /* SAMPLER STATES */ static void si_bind_sampler_states(struct pipe_context *ctx, unsigned shader, @@ -762,6 +788,19 @@ static void si_desc_reset_buffer_offset(struct pipe_context *ctx, S_008F04_BASE_ADDRESS_HI(va >> 32); } +/* TEXTURE METADATA ENABLE/DISABLE */ + +/* CMASK can be enabled (for fast clear) and disabled (for texture export) + * while the texture is bound, possibly by a different context. In that case, + * call this function to update compressed_colortex_masks. + */ +void si_update_compressed_colortex_masks(struct si_context *sctx) +{ + for (int i = 0; i < SI_NUM_SHADERS; ++i) { + si_samplers_update_compressed_colortex_mask(&sctx->samplers[i]); + } +} + /* BUFFER DISCARD/INVALIDATION */ /* Reallocate a buffer a update all resource bindings where the buffer is diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index fb16d0f2953..60c34f19e55 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -249,6 +249,7 @@ void si_all_descriptors_begin_new_cs(struct si_context *sctx); void si_upload_const_buffer(struct si_context *sctx, struct r600_resource **rbuffer, const uint8_t *ptr, unsigned size, uint32_t *const_offset); void si_shader_change_notify(struct si_context *sctx); +void si_update_compressed_colortex_masks(struct si_context *sctx); void si_emit_shader_userdata(struct si_context *sctx, struct r600_atom *atom); /* si_state.c */ -- cgit v1.2.3 From 417b6721a007a1e6b425758ffce32fd805d81f16 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Thu, 10 Mar 2016 17:57:41 +0100 Subject: radeonsi: Lazily re-set sampler views after disabling DCC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clear DCC flags if necessary when binding a new sampler view. v2: Do not reset DCC flags of bound sampler views. v3: Check that we have a real texture (Nicolai) Signed-off-by: Bas Nieuwenhuizen Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeon/r600_texture.c | 2 -- src/gallium/drivers/radeonsi/si_descriptors.c | 11 ++++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 6b2d9096525..115c7289c4c 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -311,8 +311,6 @@ static void r600_texture_disable_dcc(struct r600_common_screen *rscreen, /* Notify all contexts about the change. */ r600_dirty_all_framebuffer_states(rscreen); - - /* TODO: re-set all sampler views and images, but how? */ } static boolean r600_texture_get_handle(struct pipe_screen* screen, diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 9aa48772975..11b902516e0 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -185,12 +185,17 @@ static void si_set_sampler_view(struct si_context *sctx, struct si_sampler_views *views, unsigned slot, struct pipe_sampler_view *view) { - if (views->views[slot] == view) + struct si_sampler_view *rview = (struct si_sampler_view*)view; + + if (view && view->texture && view->texture->target != PIPE_BUFFER && + G_008F28_COMPRESSION_EN(rview->state[6]) && + ((struct r600_texture*)view->texture)->dcc_offset == 0) { + rview->state[6] &= C_008F28_COMPRESSION_EN & + C_008F28_ALPHA_IS_ON_MSB; + } else if (views->views[slot] == view) return; if (view) { - struct si_sampler_view *rview = - (struct si_sampler_view*)view; struct r600_texture *rtex = (struct r600_texture *)view->texture; si_sampler_view_add_buffer(sctx, view->texture); -- cgit v1.2.3 From 28d2a7e67c4e8a9835710e5775cd758aa7e27f47 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Fri, 11 Mar 2016 11:07:38 -0500 Subject: radeonsi: avoid crash when a sampler state is bound for a buffer texture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sampler states don't really make sense with buffer textures, but they can be set anyway, so we need to be defensive here. This bug was lurking for a while and was finally noticed due to PBO uploads setting sampler states. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94284 Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Marek Olšák Tested-by: Laurent Carlier Tested-by: Shawn Starr --- src/gallium/drivers/radeonsi/si_descriptors.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 11b902516e0..d12b3e6b28a 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -329,6 +329,7 @@ static void si_bind_sampler_states(struct pipe_context *ctx, unsigned shader, */ if (samplers->views.views[i] && samplers->views.views[i]->texture && + samplers->views.views[i]->texture->target != PIPE_BUFFER && ((struct r600_texture*)samplers->views.views[i]->texture)->fmask.size) continue; -- cgit v1.2.3 From 4de25fa7b050a296b2f1a4504e568dfce5d0a295 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Fri, 11 Mar 2016 18:20:00 -0500 Subject: radeonsi: set DEPTH_BEFORE_SHADER based on FS_EARLY_DEPTH_STENCIL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Marek Olšák --- src/gallium/drivers/radeonsi/si_state_shaders.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/drivers/radeonsi') diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 321b87d80a6..5fe1f7960f3 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -1154,6 +1154,9 @@ static void *si_create_shader_selector(struct pipe_context *ctx, break; } + if (sel->info.properties[TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL]) + sel->db_shader_control |= S_02880C_DEPTH_BEFORE_SHADER(1); + /* Compile the main shader part for use with a prolog and/or epilog. */ if (sel->type != PIPE_SHADER_GEOMETRY && !sscreen->use_monolithic_shaders) { -- cgit v1.2.3