void (*emit_func)(struct si_context *ctx, struct r600_atom *state))
{
atom->emit = (void*)emit_func;
- atom->dirty = false;
atom->id = list_elem - sctx->atoms.array + 1; /* index+1 in the atom array */
*list_elem = atom;
}
*
* Reproducible with Unigine Heaven 4.0 and drirc missing.
*/
- if (blend->dual_src_blend &&
- (sctx->ps_shader->ps_colors_written & 0x3) != 0x3)
+ if (blend && blend->dual_src_blend &&
+ sctx->ps_shader.cso &&
+ (sctx->ps_shader.cso->ps_colors_written & 0x3) != 0x3)
mask = 0;
radeon_set_context_reg(cs, R_028238_CB_TARGET_MASK, mask);
{
struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
- if (!rs || !sctx->framebuffer.state.zsbuf)
+ if (!rs || !rs->uses_poly_offset || !sctx->framebuffer.state.zsbuf)
return;
switch (sctx->framebuffer.state.zsbuf->texture->format) {
rs->two_side = state->light_twoside;
rs->multisample_enable = state->multisample;
+ rs->force_persample_interp = state->force_persample_interp;
rs->clip_plane_enable = state->clip_plane_enable;
rs->line_stipple_enable = state->line_stipple_enable;
rs->poly_stipple_enable = state->poly_stipple_enable;
rs->line_smooth = state->line_smooth;
rs->poly_smooth = state->poly_smooth;
-
+ rs->uses_poly_offset = state->offset_point || state->offset_line ||
+ state->offset_tri;
+ rs->clamp_fragment_color = state->clamp_fragment_color;
rs->flatshade = state->flatshade;
rs->sprite_coord_enable = state->sprite_coord_enable;
+ rs->rasterizer_discard = state->rasterizer_discard;
rs->pa_sc_line_stipple = state->line_stipple_enable ?
S_028A0C_LINE_PATTERN(state->line_stipple_pattern) |
S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0;
state->fill_back != PIPE_POLYGON_MODE_FILL) |
S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(state->fill_front)) |
S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(state->fill_back)));
+ si_pm4_set_reg(pm4, R_00B130_SPI_SHADER_USER_DATA_VS_0 +
+ SI_SGPR_VS_STATE_BITS * 4, state->clamp_vertex_color);
/* Precalculate polygon offset states for 16-bit, 24-bit, and 32-bit zbuffers. */
for (i = 0; i < 3; i++) {
S_028000_STENCIL_COPY(sctx->dbcb_stencil_copy_enabled) |
S_028000_COPY_CENTROID(1) |
S_028000_COPY_SAMPLE(sctx->dbcb_copy_sample));
- } else if (sctx->db_inplace_flush_enabled) {
+ } else if (sctx->db_flush_depth_inplace || sctx->db_flush_stencil_inplace) {
radeon_emit(cs,
- S_028000_DEPTH_COMPRESS_DISABLE(1) |
- S_028000_STENCIL_COMPRESS_DISABLE(1));
+ S_028000_DEPTH_COMPRESS_DISABLE(sctx->db_flush_depth_inplace) |
+ S_028000_STENCIL_COMPRESS_DISABLE(sctx->db_flush_stencil_inplace));
} else if (sctx->db_depth_clear) {
radeon_emit(cs, S_028000_DEPTH_CLEAR_ENABLE(1));
} else {
}
}
-static unsigned si_tex_dim(unsigned dim, unsigned nr_samples)
+static unsigned si_tex_dim(unsigned res_target, unsigned view_target,
+ unsigned nr_samples)
{
- switch (dim) {
+ if (view_target == PIPE_TEXTURE_CUBE ||
+ view_target == PIPE_TEXTURE_CUBE_ARRAY)
+ res_target = view_target;
+
+ switch (res_target) {
default:
case PIPE_TEXTURE_1D:
return V_008F1C_SQ_RSRC_IMG_1D;
surf->cb_color_info = color_info;
surf->cb_color_attrib = color_attrib;
- if (sctx->b.chip_class >= VI)
- surf->cb_dcc_control = S_028C78_OVERWRITE_COMBINER_DISABLE(1);
+ if (sctx->b.chip_class >= VI && rtex->dcc_buffer) {
+ 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)
+ max_uncompressed_block_size = 0;
+ else if (rtex->surface.bpe == 2)
+ max_uncompressed_block_size = 1;
+ }
+
+ 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;
+ }
if (rtex->fmask.size) {
surf->cb_color_fmask = (offset + rtex->fmask.offset) >> 8;
if (tex->cmask_buffer && tex->cmask_buffer != &tex->resource) {
radeon_add_to_buffer_list(&sctx->b, &sctx->b.rings.gfx,
tex->cmask_buffer, RADEON_USAGE_READWRITE,
- RADEON_PRIO_COLOR_META);
+ RADEON_PRIO_CMASK);
+ }
+
+ if (tex->dcc_buffer && tex->dcc_buffer != &tex->resource) {
+ radeon_add_to_buffer_list(&sctx->b, &sctx->b.rings.gfx,
+ tex->dcc_buffer, RADEON_USAGE_READWRITE,
+ RADEON_PRIO_DCC);
}
radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C,
radeon_emit(cs, tex->color_clear_value[1]); /* R_028C90_CB_COLOR0_CLEAR_WORD1 */
if (sctx->b.chip_class >= VI)
- radeon_emit(cs, 0); /* R_028C94_CB_COLOR0_DCC_BASE */
+ radeon_emit(cs, cb->cb_dcc_base); /* R_028C94_CB_COLOR0_DCC_BASE */
}
/* set CB_COLOR1_INFO for possible dual-src blending */
if (i == 1 && state->cbufs[0] &&
if (zb->db_htile_data_base) {
radeon_add_to_buffer_list(&sctx->b, &sctx->b.rings.gfx,
rtex->htile_buffer, RADEON_USAGE_READWRITE,
- RADEON_PRIO_DEPTH_META);
+ RADEON_PRIO_HTILE);
}
radeon_set_context_reg(cs, R_028008_DB_DEPTH_VIEW, zb->db_depth_view);
struct radeon_surf_level *surflevel;
int first_non_void;
uint64_t va;
+ unsigned last_layer = state->u.tex.last_layer;
if (view == NULL)
return NULL;
pipe_resource_reference(&view->base.texture, texture);
view->resource = &tmp->resource;
+ 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) {
unsigned stride, num_records;
} 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;
+
va = tmp->resource.gpu_address + surflevel[base_level].offset;
view->state[0] = va >> 8;
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, texture->nr_samples)));
+ 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(state->u.tex.last_layer));
- view->state[6] = 0;
- view->state[7] = 0;
+ S_008F24_LAST_ARRAY(last_layer));
+
+ if (tmp->dcc_buffer) {
+ uint64_t dcc_offset = surflevel[base_level].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;
+ } else {
+ view->state[6] = 0;
+ view->state[7] = 0;
+ }
/* Initialize the sampler view for FMASK. */
if (tmp->fmask.size) {
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, 0));
+ 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 - 1);
view->fmask_state[5] = S_008F24_BASE_ARRAY(state->u.tex.first_layer) |
- S_008F24_LAST_ARRAY(state->u.tex.last_layer);
+ S_008F24_LAST_ARRAY(last_layer);
view->fmask_state[6] = 0;
view->fmask_state[7] = 0;
}
static void *si_create_sampler_state(struct pipe_context *ctx,
const struct pipe_sampler_state *state)
{
+ struct si_context *sctx = (struct si_context *)ctx;
struct si_sampler_state *rstate = CALLOC_STRUCT(si_sampler_state);
unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 2 : 0;
- unsigned border_color_type;
+ unsigned border_color_type, border_color_index = 0;
if (rstate == NULL) {
return NULL;
}
- if (sampler_state_needs_border_color(state))
- border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER;
- else
+ if (!sampler_state_needs_border_color(state))
+ border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
+ else if (state->border_color.f[0] == 0 &&
+ state->border_color.f[1] == 0 &&
+ state->border_color.f[2] == 0 &&
+ state->border_color.f[3] == 0)
border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
+ else if (state->border_color.f[0] == 0 &&
+ state->border_color.f[1] == 0 &&
+ state->border_color.f[2] == 0 &&
+ state->border_color.f[3] == 1)
+ border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK;
+ else if (state->border_color.f[0] == 1 &&
+ state->border_color.f[1] == 1 &&
+ state->border_color.f[2] == 1 &&
+ state->border_color.f[3] == 1)
+ border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE;
+ else {
+ int i;
+
+ border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER;
+
+ /* Check if the border has been uploaded already. */
+ for (i = 0; i < sctx->border_color_count; i++)
+ if (memcmp(&sctx->border_color_table[i], &state->border_color,
+ sizeof(state->border_color)) == 0)
+ break;
+
+ if (i >= SI_MAX_BORDER_COLORS) {
+ /* Getting 4096 unique border colors is very unlikely. */
+ fprintf(stderr, "radeonsi: The border color table is full. "
+ "Any new border colors will be just black. "
+ "Please file a bug.\n");
+ border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
+ } else {
+ if (i == sctx->border_color_count) {
+ /* Upload a new border color. */
+ memcpy(&sctx->border_color_table[i], &state->border_color,
+ sizeof(state->border_color));
+ util_memcpy_cpu_to_le32(&sctx->border_color_map[i],
+ &state->border_color,
+ sizeof(state->border_color));
+ sctx->border_color_count++;
+ }
+
+ border_color_index = i;
+ }
+ }
rstate->val[0] = (S_008F30_CLAMP_X(si_tex_wrap(state->wrap_s)) |
S_008F30_CLAMP_Y(si_tex_wrap(state->wrap_t)) |
S_008F38_XY_MAG_FILTER(si_tex_filter(state->mag_img_filter) | aniso_flag_offset) |
S_008F38_XY_MIN_FILTER(si_tex_filter(state->min_img_filter) | aniso_flag_offset) |
S_008F38_MIP_FILTER(si_tex_mipfilter(state->min_mip_filter)));
- rstate->val[3] = S_008F3C_BORDER_COLOR_TYPE(border_color_type);
-
- if (border_color_type == V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER) {
- memcpy(rstate->border_color, state->border_color.ui,
- sizeof(rstate->border_color));
- }
-
+ rstate->val[3] = S_008F3C_BORDER_COLOR_PTR(border_color_index) |
+ S_008F3C_BORDER_COLOR_TYPE(border_color_type);
return rstate;
}
-/* Upload border colors and update the pointers in resource descriptors.
- * There can only be 4096 border colors per context.
- *
- * XXX: This is broken if the buffer gets reallocated.
- */
-static void si_set_border_colors(struct si_context *sctx, unsigned count,
- void **states)
-{
- struct si_sampler_state **rstates = (struct si_sampler_state **)states;
- uint32_t *border_color_table = NULL;
- int i, j;
-
- for (i = 0; i < count; i++) {
- if (rstates[i] &&
- G_008F3C_BORDER_COLOR_TYPE(rstates[i]->val[3]) ==
- V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER) {
- if (!sctx->border_color_table ||
- ((sctx->border_color_offset + count - i) &
- C_008F3C_BORDER_COLOR_PTR)) {
- r600_resource_reference(&sctx->border_color_table, NULL);
- sctx->border_color_offset = 0;
-
- sctx->border_color_table =
- si_resource_create_custom(&sctx->screen->b.b,
- PIPE_USAGE_DYNAMIC,
- 4096 * 4 * 4);
- }
-
- if (!border_color_table) {
- border_color_table =
- sctx->b.ws->buffer_map(sctx->border_color_table->cs_buf,
- sctx->b.rings.gfx.cs,
- PIPE_TRANSFER_WRITE |
- PIPE_TRANSFER_UNSYNCHRONIZED);
- }
-
- for (j = 0; j < 4; j++) {
- border_color_table[4 * sctx->border_color_offset + j] =
- util_le32_to_cpu(rstates[i]->border_color[j]);
- }
-
- rstates[i]->val[3] &= C_008F3C_BORDER_COLOR_PTR;
- rstates[i]->val[3] |= S_008F3C_BORDER_COLOR_PTR(sctx->border_color_offset++);
- }
- }
-
- if (border_color_table) {
- struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
-
- uint64_t va_offset = sctx->border_color_table->gpu_address;
-
- si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, va_offset >> 8);
- if (sctx->b.chip_class >= CIK)
- si_pm4_set_reg(pm4, R_028084_TA_BC_BASE_ADDR_HI, va_offset >> 40);
- si_pm4_add_bo(pm4, sctx->border_color_table, RADEON_USAGE_READ,
- RADEON_PRIO_SHADER_DATA);
- si_pm4_set_state(sctx, ta_bordercolor_base, pm4);
- }
-}
-
-static void si_bind_sampler_states(struct pipe_context *ctx, unsigned shader,
- unsigned start, unsigned count,
- void **states)
-{
- struct si_context *sctx = (struct si_context *)ctx;
-
- if (!count || shader >= SI_NUM_SHADERS)
- return;
-
- si_set_border_colors(sctx, count, states);
- si_set_sampler_descriptors(sctx, shader, start, count, states);
-}
-
static void si_set_sample_mask(struct pipe_context *ctx, unsigned sample_mask)
{
struct si_context *sctx = (struct si_context *)ctx;
sctx->b.b.get_sample_position = cayman_get_sample_position;
sctx->b.b.create_sampler_state = si_create_sampler_state;
- sctx->b.b.bind_sampler_states = si_bind_sampler_states;
sctx->b.b.delete_sampler_state = si_delete_sampler_state;
sctx->b.b.create_sampler_view = si_create_sampler_view;
unsigned num_rb = MIN2(sctx->screen->b.info.r600_num_backends, 16);
unsigned rb_mask = sctx->screen->b.info.si_backend_enabled_mask;
unsigned raster_config, raster_config_1;
+ uint64_t border_color_va = sctx->border_color_buffer->gpu_address;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
int i;
if (pm4 == NULL)
return;
- si_cmd_context_control(pm4);
+ si_pm4_cmd_begin(pm4, PKT3_CONTEXT_CONTROL);
+ si_pm4_cmd_add(pm4, 0x80000000);
+ si_pm4_cmd_add(pm4, 0x80000000);
+ si_pm4_cmd_end(pm4, false);
si_pm4_set_reg(pm4, R_028A18_VGT_HOS_MAX_TESS_LEVEL, fui(64));
si_pm4_set_reg(pm4, R_028A1C_VGT_HOS_MIN_TESS_LEVEL, fui(0));
/* FIXME calculate these values somehow ??? */
- si_pm4_set_reg(pm4, R_028A54_VGT_GS_PER_ES, 0x80);
+ si_pm4_set_reg(pm4, R_028A54_VGT_GS_PER_ES, SI_GS_PER_ES);
si_pm4_set_reg(pm4, R_028A58_VGT_ES_PER_GS, 0x40);
si_pm4_set_reg(pm4, R_028A5C_VGT_GS_PER_VS, 0x2);
break;
case CHIP_KABINI:
case CHIP_MULLINS:
+ case CHIP_STONEY:
raster_config = 0x00000000;
raster_config_1 = 0x00000000;
break;
if (sctx->b.chip_class >= VI) {
si_pm4_set_reg(pm4, R_028424_CB_DCC_CONTROL,
- S_028424_OVERWRITE_COMBINER_MRT_SHARING_DISABLE(1));
+ S_028424_OVERWRITE_COMBINER_MRT_SHARING_DISABLE(1) |
+ S_028424_OVERWRITE_COMBINER_WATERMARK(4));
si_pm4_set_reg(pm4, R_028C58_VGT_VERTEX_REUSE_BLOCK_CNTL, 30);
si_pm4_set_reg(pm4, R_028C5C_VGT_OUT_DEALLOC_CNTL, 32);
}
+ if (sctx->b.family == CHIP_STONEY)
+ si_pm4_set_reg(pm4, R_028754_SX_PS_DOWNCONVERT, 0);
+
+ si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, border_color_va >> 8);
+ if (sctx->b.chip_class >= CIK)
+ si_pm4_set_reg(pm4, R_028084_TA_BC_BASE_ADDR_HI, border_color_va >> 40);
+ si_pm4_add_bo(pm4, sctx->border_color_buffer, RADEON_USAGE_READ,
+ RADEON_PRIO_BORDER_COLORS);
+
+ si_pm4_upload_indirect_buffer(sctx, pm4);
sctx->init_config = pm4;
}