struct r600_pipe_state * state = CALLOC_STRUCT(r600_pipe_state);
struct pipe_surface rat_templ;
+ struct r600_surface *surf;
+ struct r600_resource *res;
+ struct r600_context *rctx = pipe->ctx;
COMPUTE_DBG("bind rat: %i \n", id);
* of this driver. */
pipe->ctx->compute_cb_target_mask |= (0xf << (id * 4));
+ surf = (struct r600_surface*)pipe->ctx->framebuffer.cbufs[id];
+ res = (struct r600_resource*)surf->base.texture;
+
+ evergreen_init_color_surface(rctx, surf);
/* Get the CB register writes for the RAT */
- evergreen_cb(pipe->ctx, state, &pipe->ctx->framebuffer, id);
+ r600_pipe_state_add_reg_bo(state, R_028C60_CB_COLOR0_BASE + id * 0x3C,
+ surf->cb_color_base, res, RADEON_USAGE_READWRITE);
+ r600_pipe_state_add_reg(state, R_028C78_CB_COLOR0_DIM + id * 0x3C,
+ surf->cb_color_dim);
+ r600_pipe_state_add_reg_bo(state, R_028C70_CB_COLOR0_INFO + id * 0x3C,
+ surf->cb_color_info, res, RADEON_USAGE_READWRITE);
+ r600_pipe_state_add_reg(state, R_028C64_CB_COLOR0_PITCH + id * 0x3C,
+ surf->cb_color_pitch);
+ r600_pipe_state_add_reg(state, R_028C68_CB_COLOR0_SLICE + id * 0x3C,
+ surf->cb_color_slice);
+ r600_pipe_state_add_reg(state, R_028C6C_CB_COLOR0_VIEW + id * 0x3C,
+ surf->cb_color_view);
+ r600_pipe_state_add_reg_bo(state, R_028C74_CB_COLOR0_ATTRIB + id * 0x3C,
+ surf->cb_color_attrib, res, RADEON_USAGE_READWRITE);
/* Add the register blocks to the dirty list */
free(pipe->ctx->states[R600_PIPE_STATE_FRAMEBUFFER]);
r600_context_pipe_state_set(rctx, rstate);
}
-void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
- const struct pipe_framebuffer_state *state, int cb)
+void evergreen_init_color_surface(struct r600_context *rctx,
+ struct r600_surface *surf)
{
struct r600_screen *rscreen = rctx->screen;
- struct r600_resource_texture *rtex;
- struct pipe_resource * pipe_tex;
- struct r600_surface *surf;
- unsigned level = state->cbufs[cb]->u.tex.level;
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)surf->base.texture;
+ struct pipe_resource *pipe_tex = surf->base.texture;
+ unsigned level = surf->base.u.tex.level;
unsigned pitch, slice;
unsigned color_info, color_attrib, color_dim = 0;
unsigned format, swap, ntype, endian;
unsigned tile_type, macro_aspect, tile_split, bankh, bankw, nbanks;
const struct util_format_description *desc;
int i;
- bool blend_clamp = 0, blend_bypass = 0, alphatest_bypass;
-
- surf = (struct r600_surface *)state->cbufs[cb];
- rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
- pipe_tex = state->cbufs[cb]->texture;
+ bool blend_clamp = 0, blend_bypass = 0;
if (rtex->is_depth && !rtex->is_flushing_texture) {
- r600_init_flushed_depth_texture(&rctx->context,
- state->cbufs[cb]->texture, NULL);
+ r600_init_flushed_depth_texture(&rctx->context, pipe_tex, NULL);
rtex = rtex->flushed_depth_texture;
assert(rtex);
}
offset = rtex->surface.level[level].offset;
if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
offset += rtex->surface.level[level].slice_size *
- state->cbufs[cb]->u.tex.first_layer;
+ surf->base.u.tex.first_layer;
}
pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
blend_bypass = 1;
}
- /* Alpha-test is done on the first colorbuffer only. */
- if (cb == 0) {
- alphatest_bypass = ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT;
- if (rctx->alphatest_state.bypass != alphatest_bypass) {
- rctx->alphatest_state.bypass = alphatest_bypass;
- r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
- }
- }
+ surf->alphatest_bypass = ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT;
color_info |= S_028C70_FORMAT(format) |
S_028C70_COMP_SWAP(swap) |
* - 11-bit or smaller UNORM/SNORM/SRGB
* - 16-bit or smaller FLOAT
*/
- /* XXX: This should probably be the same for all CBs if we want
- * useful alpha tests. */
if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
((desc->channel[i].size < 12 &&
desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
(desc->channel[i].size < 17 &&
desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) {
color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
- } else {
- rctx->export_16bpc = false;
- }
-
- /* Alpha-test is done on the first colorbuffer only. */
- if (cb == 0 && rctx->alphatest_state.cb0_export_16bpc != rctx->export_16bpc) {
- rctx->alphatest_state.cb0_export_16bpc = rctx->export_16bpc;
- r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+ surf->export_16bpc = true;
}
- /* for possible dual-src MRT */
- if (cb == 0 && rctx->framebuffer.nr_cbufs == 1 && !rtex->is_rat) {
- r600_pipe_state_add_reg_bo(rstate,
- R_028C70_CB_COLOR0_INFO + 1 * 0x3C,
- color_info, &rtex->resource, RADEON_USAGE_READWRITE);
- }
-
- offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
+ offset += r600_resource_va(rctx->context.screen, pipe_tex);
offset >>= 8;
/* XXX handle enabling of CB beyond BASE8 which has different offset */
- r600_pipe_state_add_reg_bo(rstate,
- R_028C60_CB_COLOR0_BASE + cb * 0x3C,
- offset, &rtex->resource, RADEON_USAGE_READWRITE);
- r600_pipe_state_add_reg(rstate,
- R_028C78_CB_COLOR0_DIM + cb * 0x3C,
- color_dim);
- r600_pipe_state_add_reg_bo(rstate,
- R_028C70_CB_COLOR0_INFO + cb * 0x3C,
- color_info, &rtex->resource, RADEON_USAGE_READWRITE);
- r600_pipe_state_add_reg(rstate,
- R_028C64_CB_COLOR0_PITCH + cb * 0x3C,
- S_028C64_PITCH_TILE_MAX(pitch));
- r600_pipe_state_add_reg(rstate,
- R_028C68_CB_COLOR0_SLICE + cb * 0x3C,
- S_028C68_SLICE_TILE_MAX(slice));
+ surf->cb_color_base = offset;
+ surf->cb_color_dim = color_dim;
+ surf->cb_color_info = color_info;
+ surf->cb_color_pitch = S_028C64_PITCH_TILE_MAX(pitch);
+ surf->cb_color_slice = S_028C68_SLICE_TILE_MAX(slice);
if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
- r600_pipe_state_add_reg(rstate,
- R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
- 0x00000000);
+ surf->cb_color_view = 0;
} else {
- r600_pipe_state_add_reg(rstate,
- R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
- S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
- S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer));
+ surf->cb_color_view = S_028C6C_SLICE_START(surf->base.u.tex.first_layer) |
+ S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer);
}
- r600_pipe_state_add_reg_bo(rstate,
- R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C,
- color_attrib,
- &rtex->resource, RADEON_USAGE_READWRITE);
+ surf->cb_color_attrib = color_attrib;
+
+ surf->color_initialized = true;
}
static void evergreen_init_depth_surface(struct r600_context *rctx,
/* build states */
rctx->export_16bpc = true;
rctx->nr_cbufs = state->nr_cbufs;
+
for (i = 0; i < state->nr_cbufs; i++) {
- evergreen_cb(rctx, rstate, state, i);
- }
- /* CB_COLOR1_INFO is already initialized for possible dual-src blending */
- if (i == 1)
+ surf = (struct r600_surface*)state->cbufs[i];
+ res = (struct r600_resource*)surf->base.texture;
+
+ if (!surf->color_initialized) {
+ evergreen_init_color_surface(rctx, surf);
+ }
+
+ if (!surf->export_16bpc) {
+ rctx->export_16bpc = false;
+ }
+
+ r600_pipe_state_add_reg_bo(rstate, R_028C60_CB_COLOR0_BASE + i * 0x3C,
+ surf->cb_color_base, res, RADEON_USAGE_READWRITE);
+ r600_pipe_state_add_reg(rstate, R_028C78_CB_COLOR0_DIM + i * 0x3C,
+ surf->cb_color_dim);
+ r600_pipe_state_add_reg_bo(rstate, R_028C70_CB_COLOR0_INFO + i * 0x3C,
+ surf->cb_color_info, res, RADEON_USAGE_READWRITE);
+ r600_pipe_state_add_reg(rstate, R_028C64_CB_COLOR0_PITCH + i * 0x3C,
+ surf->cb_color_pitch);
+ r600_pipe_state_add_reg(rstate, R_028C68_CB_COLOR0_SLICE + i * 0x3C,
+ surf->cb_color_slice);
+ r600_pipe_state_add_reg(rstate, R_028C6C_CB_COLOR0_VIEW + i * 0x3C,
+ surf->cb_color_view);
+ r600_pipe_state_add_reg_bo(rstate, R_028C74_CB_COLOR0_ATTRIB + i * 0x3C,
+ surf->cb_color_attrib, res, RADEON_USAGE_READWRITE);
+ }
+ /* set CB_COLOR1_INFO for possible dual-src blending */
+ if (i == 1 && !((struct r600_resource_texture*)res)->is_rat) {
+ r600_pipe_state_add_reg_bo(rstate, R_028C70_CB_COLOR0_INFO + 1 * 0x3C,
+ surf->cb_color_info, res, RADEON_USAGE_READWRITE);
i++;
+ }
for (; i < 8 ; i++) {
r600_pipe_state_add_reg(rstate, R_028C70_CB_COLOR0_INFO + i * 0x3C, 0);
}
+ /* Update alpha-test state dependencies.
+ * Alpha-test is done on the first colorbuffer only. */
+ if (state->nr_cbufs) {
+ surf = (struct r600_surface*)state->cbufs[0];
+ if (rctx->alphatest_state.bypass != surf->alphatest_bypass) {
+ rctx->alphatest_state.bypass = surf->alphatest_bypass;
+ r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+ }
+ if (rctx->alphatest_state.cb0_export_16bpc != surf->export_16bpc) {
+ rctx->alphatest_state.cb0_export_16bpc = surf->export_16bpc;
+ r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+ }
+ }
+
if (state->zsbuf) {
surf = (struct r600_surface*)state->zsbuf;
res = (struct r600_resource*)surf->base.texture;
rctx->cb_misc_state.nr_cbufs = state->nr_cbufs;
r600_atom_dirty(rctx, &rctx->cb_misc_state.atom);
}
+
+ if (state->nr_cbufs == 0 && rctx->alphatest_state.bypass) {
+ rctx->alphatest_state.bypass = false;
+ r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+ }
}
static void evergreen_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom *atom)
enum pipe_texture_target target,
unsigned sample_count,
unsigned usage);
-void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
- const struct pipe_framebuffer_state *state, int cb);
-
-
+void evergreen_init_color_surface(struct r600_context *rctx,
+ struct r600_surface *surf);
void evergreen_update_dual_export_state(struct r600_context * rctx);
/* r600_blit.c */
struct r600_surface {
struct pipe_surface base;
+ bool color_initialized;
bool depth_initialized;
+ /* Misc. color flags. */
+ bool alphatest_bypass;
+ bool export_16bpc;
+
+ /* Color registers. */
+ unsigned cb_color_info;
+ unsigned cb_color_base;
+ unsigned cb_color_view;
+ unsigned cb_color_size; /* R600 only */
+ unsigned cb_color_frag; /* R600 only */
+ unsigned cb_color_tile; /* R600 only */
+ unsigned cb_color_dim; /* EG only */
+ unsigned cb_color_pitch; /* EG only */
+ unsigned cb_color_slice; /* EG only */
+ unsigned cb_color_attrib; /* EG only */
+
/* DB registers. */
unsigned db_depth_info; /* DB_Z_INFO (EG) or DB_DEPTH_INFO (r600) */
unsigned db_depth_base; /* DB_Z_READ/WRITE_BASE (EG) or DB_DEPTH_BASE (r600) */
r600_context_pipe_state_set(rctx, rstate);
}
-static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
- const struct pipe_framebuffer_state *state, int cb)
+static void r600_init_color_surface(struct r600_context *rctx,
+ struct r600_surface *surf)
{
- struct r600_resource_texture *rtex;
- struct r600_surface *surf;
- unsigned level = state->cbufs[cb]->u.tex.level;
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)surf->base.texture;
+ unsigned level = surf->base.u.tex.level;
unsigned pitch, slice;
unsigned color_info;
unsigned format, swap, ntype, endian;
unsigned offset;
const struct util_format_description *desc;
int i;
- bool blend_bypass = 0, blend_clamp = 1, alphatest_bypass;
-
- surf = (struct r600_surface *)state->cbufs[cb];
- rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
+ bool blend_bypass = 0, blend_clamp = 1;
if (rtex->is_depth && !rtex->is_flushing_texture) {
+ r600_init_flushed_depth_texture(&rctx->context, surf->base.texture, NULL);
rtex = rtex->flushed_depth_texture;
+ assert(rtex);
}
offset = rtex->surface.level[level].offset;
if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
offset += rtex->surface.level[level].slice_size *
- state->cbufs[cb]->u.tex.first_layer;
+ surf->base.u.tex.first_layer;
}
pitch = rtex->surface.level[level].nblk_x / 8 - 1;
slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
blend_bypass = 1;
}
- /* Alpha-test is done on the first colorbuffer only. */
- if (cb == 0) {
- alphatest_bypass = ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT;
- if (rctx->alphatest_state.bypass != alphatest_bypass) {
- rctx->alphatest_state.bypass = alphatest_bypass;
- r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
- }
- }
+ surf->alphatest_bypass = ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT;
color_info |= S_0280A0_FORMAT(format) |
S_0280A0_COMP_SWAP(swap) |
G_0280A0_BLEND_CLAMP(color_info) &&
!G_0280A0_BLEND_FLOAT32(color_info)) {
color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
- } else {
- rctx->export_16bpc = false;
+ surf->export_16bpc = true;
}
} else {
/* EXPORT_NORM can be enabled if:
(desc->channel[i].size < 17 &&
desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) {
color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
- } else {
- rctx->export_16bpc = false;
+ surf->export_16bpc = true;
}
}
- /* for possible dual-src MRT write color info 1 */
- if (cb == 0 && rctx->framebuffer.nr_cbufs == 1) {
- r600_pipe_state_add_reg_bo(rstate,
- R_0280A0_CB_COLOR0_INFO + 1 * 4,
- color_info, &rtex->resource, RADEON_USAGE_READWRITE);
- }
-
- r600_pipe_state_add_reg_bo(rstate,
- R_028040_CB_COLOR0_BASE + cb * 4,
- offset >> 8, &rtex->resource, RADEON_USAGE_READWRITE);
- r600_pipe_state_add_reg_bo(rstate,
- R_0280A0_CB_COLOR0_INFO + cb * 4,
- color_info, &rtex->resource, RADEON_USAGE_READWRITE);
- r600_pipe_state_add_reg(rstate,
- R_028060_CB_COLOR0_SIZE + cb * 4,
- S_028060_PITCH_TILE_MAX(pitch) |
- S_028060_SLICE_TILE_MAX(slice));
+ surf->cb_color_base = offset >> 8;
+ surf->cb_color_info = color_info;
+ surf->cb_color_size = S_028060_PITCH_TILE_MAX(pitch) |
+ S_028060_SLICE_TILE_MAX(slice);
if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
- r600_pipe_state_add_reg(rstate,
- R_028080_CB_COLOR0_VIEW + cb * 4,
- 0x00000000);
+ surf->cb_color_view = 0;
} else {
- r600_pipe_state_add_reg(rstate,
- R_028080_CB_COLOR0_VIEW + cb * 4,
- S_028080_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
- S_028080_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer));
+ surf->cb_color_view = S_028080_SLICE_START(surf->base.u.tex.first_layer) |
+ S_028080_SLICE_MAX(surf->base.u.tex.last_layer);
}
- r600_pipe_state_add_reg_bo(rstate,
- R_0280E0_CB_COLOR0_FRAG + cb * 4,
- 0, &rtex->resource, RADEON_USAGE_READWRITE);
- r600_pipe_state_add_reg_bo(rstate,
- R_0280C0_CB_COLOR0_TILE + cb * 4,
- 0, &rtex->resource, RADEON_USAGE_READWRITE);
+
+ surf->color_initialized = true;
}
static void r600_init_depth_surface(struct r600_context *rctx,
struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
struct r600_surface *surf;
struct r600_resource *res;
- uint32_t tl, br;
+ uint32_t tl, br, i;
if (rstate == NULL)
return;
rctx->export_16bpc = true;
rctx->nr_cbufs = state->nr_cbufs;
- for (int i = 0; i < state->nr_cbufs; i++) {
- r600_cb(rctx, rstate, state, i);
+ for (i = 0; i < state->nr_cbufs; i++) {
+ surf = (struct r600_surface*)state->cbufs[i];
+ res = (struct r600_resource*)surf->base.texture;
+
+ if (!surf->color_initialized) {
+ r600_init_color_surface(rctx, surf);
+ }
+
+ if (!surf->export_16bpc) {
+ rctx->export_16bpc = false;
+ }
+
+ r600_pipe_state_add_reg_bo(rstate, R_028040_CB_COLOR0_BASE + i * 4,
+ surf->cb_color_base, res, RADEON_USAGE_READWRITE);
+ r600_pipe_state_add_reg_bo(rstate, R_0280A0_CB_COLOR0_INFO + i * 4,
+ surf->cb_color_info, res, RADEON_USAGE_READWRITE);
+ r600_pipe_state_add_reg(rstate, R_028060_CB_COLOR0_SIZE + i * 4,
+ surf->cb_color_size);
+ r600_pipe_state_add_reg(rstate, R_028080_CB_COLOR0_VIEW + i * 4,
+ surf->cb_color_view);
+ r600_pipe_state_add_reg_bo(rstate, R_0280E0_CB_COLOR0_FRAG + i * 4,
+ surf->cb_color_frag, res, RADEON_USAGE_READWRITE);
+ r600_pipe_state_add_reg_bo(rstate, R_0280C0_CB_COLOR0_TILE + i * 4,
+ surf->cb_color_tile, res, RADEON_USAGE_READWRITE);
+ }
+ /* set CB_COLOR1_INFO for possible dual-src blending */
+ if (i == 1) {
+ r600_pipe_state_add_reg_bo(rstate, R_0280A0_CB_COLOR0_INFO + 1 * 4,
+ surf->cb_color_info, res, RADEON_USAGE_READWRITE);
+ i++;
+ }
+
+ /* Update alpha-test state dependencies.
+ * Alpha-test is done on the first colorbuffer only. */
+ if (state->nr_cbufs) {
+ surf = (struct r600_surface*)state->cbufs[0];
+ if (rctx->alphatest_state.bypass != surf->alphatest_bypass) {
+ rctx->alphatest_state.bypass = surf->alphatest_bypass;
+ r600_atom_dirty(rctx, &rctx->alphatest_state.atom);
+ }
}
+
if (state->zsbuf) {
surf = (struct r600_surface*)state->zsbuf;
res = (struct r600_resource*)surf->base.texture;