R600_CONTEXT_FLUSH_AND_INV_CB |
R600_CONTEXT_FLUSH_AND_INV |
R600_CONTEXT_WAIT_3D_IDLE;
+ rctx->framebuffer.do_update_surf_dirtiness = true;
}
static unsigned r600_conv_pipe_prim(unsigned prim)
}
/* Compute the key for the hw shader variant */
-static inline union r600_shader_key r600_shader_selector_key(struct pipe_context * ctx,
- struct r600_pipe_shader_selector * sel)
+static inline void r600_shader_selector_key(const struct pipe_context *ctx,
+ const struct r600_pipe_shader_selector *sel,
+ union r600_shader_key *key)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
- union r600_shader_key key;
- memset(&key, 0, sizeof(key));
+ const struct r600_context *rctx = (struct r600_context *)ctx;
+ memset(key, 0, sizeof(*key));
switch (sel->type) {
case PIPE_SHADER_VERTEX: {
- key.vs.as_ls = (rctx->tes_shader != NULL);
- if (!key.vs.as_ls)
- key.vs.as_es = (rctx->gs_shader != NULL);
+ key->vs.as_ls = (rctx->tes_shader != NULL);
+ if (!key->vs.as_ls)
+ key->vs.as_es = (rctx->gs_shader != NULL);
if (rctx->ps_shader->current->shader.gs_prim_id_input && !rctx->gs_shader) {
- key.vs.as_gs_a = true;
- key.vs.prim_id_out = rctx->ps_shader->current->shader.input[rctx->ps_shader->current->shader.ps_prim_id_input].spi_sid;
+ key->vs.as_gs_a = true;
+ key->vs.prim_id_out = rctx->ps_shader->current->shader.input[rctx->ps_shader->current->shader.ps_prim_id_input].spi_sid;
}
break;
}
case PIPE_SHADER_GEOMETRY:
break;
case PIPE_SHADER_FRAGMENT: {
- key.ps.color_two_side = rctx->rasterizer && rctx->rasterizer->two_side;
- key.ps.alpha_to_one = rctx->alpha_to_one &&
+ key->ps.color_two_side = rctx->rasterizer && rctx->rasterizer->two_side;
+ key->ps.alpha_to_one = rctx->alpha_to_one &&
rctx->rasterizer && rctx->rasterizer->multisample_enable &&
!rctx->framebuffer.cb0_is_integer;
- key.ps.nr_cbufs = rctx->framebuffer.state.nr_cbufs;
+ key->ps.nr_cbufs = rctx->framebuffer.state.nr_cbufs;
/* Dual-source blending only makes sense with nr_cbufs == 1. */
- if (key.ps.nr_cbufs == 1 && rctx->dual_src_blend)
- key.ps.nr_cbufs = 2;
+ if (key->ps.nr_cbufs == 1 && rctx->dual_src_blend)
+ key->ps.nr_cbufs = 2;
break;
}
case PIPE_SHADER_TESS_EVAL:
- key.tes.as_es = (rctx->gs_shader != NULL);
+ key->tes.as_es = (rctx->gs_shader != NULL);
break;
case PIPE_SHADER_TESS_CTRL:
- key.tcs.prim_mode = rctx->tes_shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
+ key->tcs.prim_mode = rctx->tes_shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
break;
default:
assert(0);
}
-
- return key;
}
/* Select the hw shader variant depending on the current state.
struct r600_pipe_shader * shader = NULL;
int r;
- memset(&key, 0, sizeof(key));
- key = r600_shader_selector_key(ctx, sel);
+ r600_shader_selector_key(ctx, sel, &key);
/* Check if we don't need to change anything.
* This path is also used for most shaders that don't need multiple
if (sel->type == PIPE_SHADER_FRAGMENT &&
sel->num_shaders == 0) {
sel->nr_ps_max_color_exports = shader->shader.nr_ps_max_color_exports;
- key = r600_shader_selector_key(ctx, sel);
+ r600_shader_selector_key(ctx, sel, &key);
}
memcpy(&shader->key, &key, sizeof(key));
{
struct r600_context *rctx = (struct r600_context *)ctx;
- if (!state)
+ if (!state || rctx->vs_shader == state)
return;
rctx->vs_shader = (struct r600_pipe_shader_selector *)state;
{
struct r600_context *rctx = (struct r600_context *)ctx;
+ if (state == rctx->gs_shader)
+ return;
+
rctx->gs_shader = (struct r600_pipe_shader_selector *)state;
r600_update_vs_writes_viewport_index(&rctx->b, r600_get_vs_info(rctx));
{
struct r600_context *rctx = (struct r600_context *)ctx;
+ if (state == rctx->tes_shader)
+ return;
+
rctx->tes_shader = (struct r600_pipe_shader_selector *)state;
r600_update_vs_writes_viewport_index(&rctx->b, r600_get_vs_info(rctx));
S_028AB4_REUSE_OFF(state->vs_out_viewport));
}
+/* rast_prim is the primitive type after GS. */
+static inline void r600_emit_rasterizer_prim_state(struct r600_context *rctx)
+{
+ struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ enum pipe_prim_type rast_prim = rctx->current_rast_prim;
+
+ /* Skip this if not rendering lines. */
+ if (rast_prim != PIPE_PRIM_LINES &&
+ rast_prim != PIPE_PRIM_LINE_LOOP &&
+ rast_prim != PIPE_PRIM_LINE_STRIP &&
+ rast_prim != PIPE_PRIM_LINES_ADJACENCY &&
+ rast_prim != PIPE_PRIM_LINE_STRIP_ADJACENCY)
+ return;
+
+ if (rast_prim == rctx->last_rast_prim)
+ return;
+
+ /* For lines, reset the stipple pattern at each primitive. Otherwise,
+ * reset the stipple pattern at each packet (line strips, line loops).
+ */
+ radeon_set_context_reg(cs, R_028A0C_PA_SC_LINE_STIPPLE,
+ S_028A0C_AUTO_RESET_CNTL(rast_prim == PIPE_PRIM_LINES ? 1 : 2) |
+ (rctx->rasterizer ? rctx->rasterizer->pa_sc_line_stipple : 0));
+ rctx->last_rast_prim = rast_prim;
+}
+
static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
{
struct r600_context *rctx = (struct r600_context *)ctx;
return;
}
- if (unlikely(!rctx->vs_shader || !rctx->ps_shader)) {
+ if (unlikely(!rctx->vs_shader)) {
+ assert(0);
+ return;
+ }
+ if (unlikely(!rctx->ps_shader &&
+ (!rctx->rasterizer || !rctx->rasterizer->rasterizer_discard))) {
assert(0);
return;
}
if (unlikely(dirty_tex_counter != rctx->b.last_dirty_tex_counter)) {
rctx->b.last_dirty_tex_counter = dirty_tex_counter;
r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom);
+ rctx->framebuffer.do_update_surf_dirtiness = true;
}
if (!r600_update_derived_state(rctx)) {
return;
}
+ rctx->current_rast_prim = (rctx->gs_shader)? rctx->gs_shader->gs_output_prim
+ : (rctx->tes_shader)? rctx->tes_shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE]
+ : info->mode;
+
if (info->indexed) {
/* Initialize the index buffer struct. */
pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer);
/* Update the primitive type. */
if (rctx->last_primitive_type != info->mode) {
- unsigned ls_mask = 0;
-
- if (info->mode == PIPE_PRIM_LINES)
- ls_mask = 1;
- else if (info->mode == PIPE_PRIM_LINE_STRIP ||
- info->mode == PIPE_PRIM_LINE_LOOP)
- ls_mask = 2;
-
- radeon_set_context_reg(cs, R_028A0C_PA_SC_LINE_STIPPLE,
- S_028A0C_AUTO_RESET_CNTL(ls_mask) |
- (rctx->rasterizer ? rctx->rasterizer->pa_sc_line_stipple : 0));
+ r600_emit_rasterizer_prim_state(rctx);
radeon_set_config_reg(cs, R_008958_VGT_PRIMITIVE_TYPE,
r600_conv_pipe_prim(info->mode));
radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_SQ_NON_EVENT));
}
- /* Set the depth buffer as dirty. */
- if (rctx->framebuffer.state.zsbuf) {
- struct pipe_surface *surf = rctx->framebuffer.state.zsbuf;
- struct r600_texture *rtex = (struct r600_texture *)surf->texture;
+ if (rctx->framebuffer.do_update_surf_dirtiness) {
+ /* Set the depth buffer as dirty. */
+ if (rctx->framebuffer.state.zsbuf) {
+ struct pipe_surface *surf = rctx->framebuffer.state.zsbuf;
+ struct r600_texture *rtex = (struct r600_texture *)surf->texture;
- rtex->dirty_level_mask |= 1 << surf->u.tex.level;
+ rtex->dirty_level_mask |= 1 << surf->u.tex.level;
- if (rtex->surface.flags & RADEON_SURF_SBUFFER)
- rtex->stencil_dirty_level_mask |= 1 << surf->u.tex.level;
- }
- if (rctx->framebuffer.compressed_cb_mask) {
- struct pipe_surface *surf;
- struct r600_texture *rtex;
- unsigned mask = rctx->framebuffer.compressed_cb_mask;
+ if (rtex->surface.flags & RADEON_SURF_SBUFFER)
+ rtex->stencil_dirty_level_mask |= 1 << surf->u.tex.level;
+ }
+ if (rctx->framebuffer.compressed_cb_mask) {
+ struct pipe_surface *surf;
+ struct r600_texture *rtex;
+ unsigned mask = rctx->framebuffer.compressed_cb_mask;
- do {
- unsigned i = u_bit_scan(&mask);
- surf = rctx->framebuffer.state.cbufs[i];
- rtex = (struct r600_texture*)surf->texture;
+ do {
+ unsigned i = u_bit_scan(&mask);
+ surf = rctx->framebuffer.state.cbufs[i];
+ rtex = (struct r600_texture*)surf->texture;
- rtex->dirty_level_mask |= 1 << surf->u.tex.level;
+ rtex->dirty_level_mask |= 1 << surf->u.tex.level;
- } while (mask);
+ } while (mask);
+ }
+ rctx->framebuffer.do_update_surf_dirtiness = false;
}
pipe_resource_reference(&ib.buffer, NULL);