summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2014-02-09 22:16:48 +0100
committerMarek Olšák <marek.olsak@amd.com>2014-02-25 16:08:17 +0100
commit629b019a40f3419b858a9591a2035f9eae45c836 (patch)
tree685534e70d61de50f66f7a4d3a946e5a93f9b540
parent6b4e03216a75ed20fb3fa0eb963a6cd5617469d7 (diff)
radeonsi: compute color surface registers only once
Same as r600g. Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c99
1 files changed, 55 insertions, 44 deletions
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 0154e5804b8..89b4242ef1f 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1572,37 +1572,31 @@ static unsigned si_tile_mode_index(struct r600_texture *rtex, unsigned level, bo
* framebuffer handling
*/
-static void si_cb(struct si_context *sctx, struct si_pm4_state *pm4,
- const struct pipe_framebuffer_state *state, int cb)
+static void si_initialize_color_surface(struct si_context *sctx,
+ struct r600_surface *surf)
{
- struct r600_texture *rtex;
- struct r600_surface *surf;
- unsigned level = state->cbufs[cb]->u.tex.level;
+ struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
+ unsigned level = surf->base.u.tex.level;
+ uint64_t offset = rtex->surface.level[level].offset;
unsigned pitch, slice;
unsigned color_info, color_attrib, color_pitch, color_view;
unsigned tile_mode_index;
unsigned format, swap, ntype, endian;
- uint64_t offset;
const struct util_format_description *desc;
int i;
unsigned blend_clamp = 0, blend_bypass = 0;
unsigned max_comp_size;
- surf = (struct r600_surface *)state->cbufs[cb];
- rtex = (struct r600_texture*)state->cbufs[cb]->texture;
-
- offset = rtex->surface.level[level].offset;
-
/* Layered rendering doesn't work with LINEAR_GENERAL.
* (LINEAR_ALIGNED and others work) */
if (rtex->surface.level[level].mode == RADEON_SURF_MODE_LINEAR) {
- assert(state->cbufs[cb]->u.tex.first_layer == state->cbufs[cb]->u.tex.last_layer);
+ assert(surf->base.u.tex.first_layer == surf->base.u.tex.last_layer);
offset += rtex->surface.level[level].slice_size *
- state->cbufs[cb]->u.tex.first_layer;
+ surf->base.u.tex.first_layer;
color_view = 0;
} else {
- color_view = S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
- S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer);
+ color_view = S_028C6C_SLICE_START(surf->base.u.tex.first_layer) |
+ S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer);
}
pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
@@ -1707,34 +1701,22 @@ static void si_cb(struct si_context *sctx, struct si_pm4_state *pm4,
color_info |= S_028C70_FAST_CLEAR(1);
}
- offset += r600_resource_va(sctx->b.b.screen, state->cbufs[cb]->texture);
- offset >>= 8;
+ offset += r600_resource_va(sctx->b.b.screen, surf->base.texture);
- si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
- si_pm4_set_reg(pm4, R_028C60_CB_COLOR0_BASE + cb * 0x3C, offset);
- si_pm4_set_reg(pm4, R_028C64_CB_COLOR0_PITCH + cb * 0x3C, color_pitch);
- si_pm4_set_reg(pm4, R_028C68_CB_COLOR0_SLICE + cb * 0x3C, S_028C68_TILE_MAX(slice));
- si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, color_view);
- si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info);
- si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C, color_attrib);
+ surf->cb_color_base = offset >> 8;
+ surf->cb_color_pitch = color_pitch;
+ surf->cb_color_slice = S_028C68_TILE_MAX(slice);
+ surf->cb_color_view = color_view;
+ surf->cb_color_info = color_info;
+ surf->cb_color_attrib = color_attrib;
if (rtex->cmask.size) {
- si_pm4_set_reg(pm4, R_028C7C_CB_COLOR0_CMASK + cb * 0x3C,
- offset + (rtex->cmask.offset >> 8));
- si_pm4_set_reg(pm4, R_028C80_CB_COLOR0_CMASK_SLICE + cb * 0x3C,
- S_028C80_TILE_MAX(rtex->cmask.slice_tile_max));
+ surf->cb_color_cmask = (offset + rtex->cmask.offset) >> 8;
+ surf->cb_color_cmask_slice = S_028C80_TILE_MAX(rtex->cmask.slice_tile_max);
}
if (rtex->fmask.size) {
- si_pm4_set_reg(pm4, R_028C84_CB_COLOR0_FMASK + cb * 0x3C,
- offset + (rtex->fmask.offset >> 8));
- si_pm4_set_reg(pm4, R_028C88_CB_COLOR0_FMASK_SLICE + cb * 0x3C,
- S_028C88_TILE_MAX(rtex->fmask.slice_tile_max));
- }
-
- /* set CB_COLOR1_INFO for possible dual-src blending */
- if (state->nr_cbufs == 1) {
- assert(cb == 0);
- si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + 1 * 0x3C, color_info);
+ surf->cb_color_fmask = (offset + rtex->fmask.offset) >> 8;
+ surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
}
/* Determine pixel shader export format */
@@ -1743,11 +1725,10 @@ static void si_cb(struct si_context *sctx, struct si_pm4_state *pm4,
((ntype == V_028C70_NUMBER_UNORM || ntype == V_028C70_NUMBER_SNORM) &&
max_comp_size <= 10) ||
(ntype == V_028C70_NUMBER_FLOAT && max_comp_size <= 16)) {
- sctx->export_16bpc |= 1 << cb;
- /* set SPI_SHADER_COL_FORMAT for possible dual-src blending */
- if (state->nr_cbufs == 1)
- sctx->export_16bpc |= 1 << 1;
+ surf->export_16bpc = true;
}
+
+ surf->color_initialized = true;
}
static void si_db(struct si_context *sctx, struct si_pm4_state *pm4,
@@ -2111,6 +2092,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
const struct pipe_framebuffer_state *state)
{
struct si_context *sctx = (struct si_context *)ctx;
+ struct r600_surface *surf = NULL;
struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
int nr_samples, i;
@@ -2131,6 +2113,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
/* build states */
sctx->export_16bpc = 0;
sctx->fb_compressed_cb_mask = 0;
+
for (i = 0; i < state->nr_cbufs; i++) {
struct r600_texture *rtex;
@@ -2140,13 +2123,41 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
continue;
}
- rtex = (struct r600_texture*)state->cbufs[i]->texture;
+ surf = (struct r600_surface*)state->cbufs[i];
+ rtex = (struct r600_texture*)surf->base.texture;
+
+ if (!surf->color_initialized) {
+ si_initialize_color_surface(sctx, surf);
+ }
- si_cb(sctx, pm4, state, i);
+ if (surf->export_16bpc) {
+ sctx->export_16bpc |= 1 << i;
+ }
if (rtex->fmask.size || rtex->cmask.size) {
sctx->fb_compressed_cb_mask |= 1 << i;
}
+
+ si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
+ si_pm4_set_reg(pm4, R_028C60_CB_COLOR0_BASE + i * 0x3C, surf->cb_color_base);
+ si_pm4_set_reg(pm4, R_028C64_CB_COLOR0_PITCH + i * 0x3C, surf->cb_color_pitch);
+ si_pm4_set_reg(pm4, R_028C68_CB_COLOR0_SLICE + i * 0x3C, surf->cb_color_slice);
+ si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + i * 0x3C, surf->cb_color_view);
+ si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + i * 0x3C, surf->cb_color_info);
+ si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + i * 0x3C, surf->cb_color_attrib);
+ si_pm4_set_reg(pm4, R_028C7C_CB_COLOR0_CMASK + i * 0x3C, surf->cb_color_cmask);
+ si_pm4_set_reg(pm4, R_028C80_CB_COLOR0_CMASK_SLICE + i * 0x3C, surf->cb_color_cmask_slice);
+ si_pm4_set_reg(pm4, R_028C84_CB_COLOR0_FMASK + i * 0x3C, surf->cb_color_fmask);
+ si_pm4_set_reg(pm4, R_028C88_CB_COLOR0_FMASK_SLICE + i * 0x3C, surf->cb_color_fmask_slice);
+ }
+ /* Set CB_COLOR1_INFO for possible dual-src blending. */
+ if (i == 1 && surf) {
+ si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + 1 * 0x3C, surf->cb_color_info);
+ /* Also set the 16BPC export. */
+ if (surf->export_16bpc) {
+ sctx->export_16bpc |= 1 << 1;
+ }
+ i++;
}
for (; i < 8; i++) {
si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + i * 0x3C,