summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/evergreen_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600/evergreen_state.c')
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c154
1 files changed, 146 insertions, 8 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 48bea1fcfe4..6896617ce93 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -2518,6 +2518,7 @@ static void evergreen_emit_constant_buffers(struct r600_context *rctx,
struct r600_resource *rbuffer;
uint64_t va;
unsigned buffer_index = ffs(dirty_mask) - 1;
+ unsigned gs_ring_buffer = (buffer_index == R600_GS_RING_CONST_BUFFER);
cb = &state->cb[buffer_index];
rbuffer = (struct r600_resource*)cb->buffer;
@@ -2526,10 +2527,12 @@ static void evergreen_emit_constant_buffers(struct r600_context *rctx,
va = r600_resource_va(&rctx->screen->b.b, &rbuffer->b.b);
va += cb->buffer_offset;
- r600_write_context_reg_flag(cs, reg_alu_constbuf_size + buffer_index * 4,
- ALIGN_DIVUP(cb->buffer_size >> 4, 16), pkt_flags);
- r600_write_context_reg_flag(cs, reg_alu_const_cache + buffer_index * 4, va >> 8,
- pkt_flags);
+ if (!gs_ring_buffer) {
+ r600_write_context_reg_flag(cs, reg_alu_constbuf_size + buffer_index * 4,
+ ALIGN_DIVUP(cb->buffer_size >> 4, 16), pkt_flags);
+ r600_write_context_reg_flag(cs, reg_alu_const_cache + buffer_index * 4, va >> 8,
+ pkt_flags);
+ }
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0) | pkt_flags);
radeon_emit(cs, r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, rbuffer, RADEON_USAGE_READ));
@@ -2539,10 +2542,12 @@ static void evergreen_emit_constant_buffers(struct r600_context *rctx,
radeon_emit(cs, va); /* RESOURCEi_WORD0 */
radeon_emit(cs, rbuffer->buf->size - cb->buffer_offset - 1); /* RESOURCEi_WORD1 */
radeon_emit(cs, /* RESOURCEi_WORD2 */
- S_030008_ENDIAN_SWAP(r600_endian_swap(32)) |
- S_030008_STRIDE(16) |
- S_030008_BASE_ADDRESS_HI(va >> 32UL));
+ S_030008_ENDIAN_SWAP(gs_ring_buffer ? ENDIAN_NONE : r600_endian_swap(32)) |
+ S_030008_STRIDE(gs_ring_buffer ? 4 : 16) |
+ S_030008_BASE_ADDRESS_HI(va >> 32UL) |
+ S_030008_DATA_FORMAT(FMT_32_32_32_32_FLOAT));
radeon_emit(cs, /* RESOURCEi_WORD3 */
+ S_03000C_UNCACHED(gs_ring_buffer ? 1 : 0) |
S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) |
S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) |
S_03000C_DST_SEL_Z(V_03000C_SQ_SEL_Z) |
@@ -2550,7 +2555,8 @@ static void evergreen_emit_constant_buffers(struct r600_context *rctx,
radeon_emit(cs, 0); /* RESOURCEi_WORD4 */
radeon_emit(cs, 0); /* RESOURCEi_WORD5 */
radeon_emit(cs, 0); /* RESOURCEi_WORD6 */
- radeon_emit(cs, 0xc0000000); /* RESOURCEi_WORD7 */
+ radeon_emit(cs, /* RESOURCEi_WORD7 */
+ S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_BUFFER));
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0) | pkt_flags);
radeon_emit(cs, r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, rbuffer, RADEON_USAGE_READ));
@@ -2714,6 +2720,63 @@ static void evergreen_emit_vertex_fetch_shader(struct r600_context *rctx, struct
radeon_emit(cs, r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, shader->buffer, RADEON_USAGE_READ));
}
+static void evergreen_emit_shader_stages(struct r600_context *rctx, struct r600_atom *a)
+{
+ struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs;
+ struct r600_shader_stages_state *state = (struct r600_shader_stages_state*)a;
+
+ uint32_t v = 0, v2 = 0;
+
+ if (state->geom_enable) {
+ v = S_028B54_ES_EN(V_028B54_ES_STAGE_REAL) |
+ S_028B54_GS_EN(1) |
+ S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER);
+
+ v2 = S_028A40_MODE(V_028A40_GS_SCENARIO_G) |
+ S_028A40_CUT_MODE(V_028A40_GS_CUT_128);
+ }
+
+ r600_write_context_reg(cs, R_028B54_VGT_SHADER_STAGES_EN, v);
+ r600_write_context_reg(cs, R_028A40_VGT_GS_MODE, v2);
+}
+
+static void evergreen_emit_gs_rings(struct r600_context *rctx, struct r600_atom *a)
+{
+ struct pipe_screen *screen = rctx->b.b.screen;
+ struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs;
+ struct r600_gs_rings_state *state = (struct r600_gs_rings_state*)a;
+ struct r600_resource *rbuffer;
+
+ r600_write_config_reg(cs, R_008040_WAIT_UNTIL, S_008040_WAIT_3D_IDLE(1));
+ radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
+ radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_VGT_FLUSH));
+
+ if (state->enable) {
+ rbuffer =(struct r600_resource*)state->esgs_ring.buffer;
+ r600_write_config_reg(cs, R_008C40_SQ_ESGS_RING_BASE,
+ (r600_resource_va(screen, &rbuffer->b.b)) >> 8);
+ radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
+ radeon_emit(cs, r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, rbuffer, RADEON_USAGE_READWRITE));
+ r600_write_config_reg(cs, R_008C44_SQ_ESGS_RING_SIZE,
+ state->esgs_ring.buffer_size >> 8);
+
+ rbuffer =(struct r600_resource*)state->gsvs_ring.buffer;
+ r600_write_config_reg(cs, R_008C48_SQ_GSVS_RING_BASE,
+ (r600_resource_va(screen, &rbuffer->b.b)) >> 8);
+ radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
+ radeon_emit(cs, r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, rbuffer, RADEON_USAGE_READWRITE));
+ r600_write_config_reg(cs, R_008C4C_SQ_GSVS_RING_SIZE,
+ state->gsvs_ring.buffer_size >> 8);
+ } else {
+ r600_write_config_reg(cs, R_008C44_SQ_ESGS_RING_SIZE, 0);
+ r600_write_config_reg(cs, R_008C4C_SQ_GSVS_RING_SIZE, 0);
+ }
+
+ r600_write_config_reg(cs, R_008040_WAIT_UNTIL, S_008040_WAIT_3D_IDLE(1));
+ radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
+ radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_VGT_FLUSH));
+}
+
void cayman_init_common_regs(struct r600_command_buffer *cb,
enum chip_class ctx_chip_class,
enum radeon_family ctx_family,
@@ -3509,6 +3572,77 @@ void evergreen_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader
shader->flatshade = rctx->rasterizer->flatshade;
}
+void evergreen_update_es_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
+{
+ struct r600_command_buffer *cb = &shader->command_buffer;
+ struct r600_shader *rshader = &shader->shader;
+
+ r600_init_command_buffer(cb, 32);
+
+ r600_store_context_reg(cb, R_028890_SQ_PGM_RESOURCES_ES,
+ S_028890_NUM_GPRS(rshader->bc.ngpr) |
+ S_028890_STACK_SIZE(rshader->bc.nstack));
+ r600_store_context_reg(cb, R_02888C_SQ_PGM_START_ES,
+ r600_resource_va(ctx->screen, (void *)shader->bo) >> 8);
+ /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
+}
+
+void evergreen_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
+{
+ struct r600_command_buffer *cb = &shader->command_buffer;
+ struct r600_shader *rshader = &shader->shader;
+ struct r600_shader *cp_shader = &shader->gs_copy_shader->shader;
+ unsigned gsvs_itemsize =
+ (cp_shader->ring_item_size * rshader->gs_max_out_vertices) >> 2;
+
+ r600_init_command_buffer(cb, 64);
+
+ /* VGT_GS_OUT_PRIM_TYPE is written by r6000_draw_vbo */
+ /* VGT_GS_MODE is written by evergreen_emit_shader_stages */
+
+ r600_store_context_reg(cb, R_028AB8_VGT_VTX_CNT_EN, 1);
+
+ r600_store_context_reg(cb, R_028B38_VGT_GS_MAX_VERT_OUT,
+ S_028B38_MAX_VERT_OUT(rshader->gs_max_out_vertices));
+
+
+/* XXX kernel checker fails
+ r600_store_context_reg(cb, R_028B90_VGT_GS_INSTANCE_CNT,
+ S_028B90_CNT(0) |
+ S_028B90_ENABLE(0));
+*/
+ r600_store_context_reg_seq(cb, R_02891C_SQ_GS_VERT_ITEMSIZE, 4);
+ r600_store_value(cb, cp_shader->ring_item_size >> 2);
+ r600_store_value(cb, 0);
+ r600_store_value(cb, 0);
+ r600_store_value(cb, 0);
+
+ r600_store_context_reg(cb, R_028900_SQ_ESGS_RING_ITEMSIZE,
+ (rshader->ring_item_size) >> 2);
+
+ r600_store_context_reg(cb, R_028904_SQ_GSVS_RING_ITEMSIZE,
+ gsvs_itemsize);
+
+ r600_store_context_reg_seq(cb, R_02892C_SQ_GSVS_RING_OFFSET_1, 3);
+ r600_store_value(cb, gsvs_itemsize);
+ r600_store_value(cb, gsvs_itemsize);
+ r600_store_value(cb, gsvs_itemsize);
+
+ /* FIXME calculate these values somehow ??? */
+ r600_store_context_reg_seq(cb, R_028A54_GS_PER_ES, 3);
+ r600_store_value(cb, 0x80); /* GS_PER_ES */
+ r600_store_value(cb, 0x100); /* ES_PER_GS */
+ r600_store_value(cb, 0x2); /* GS_PER_VS */
+
+ r600_store_context_reg(cb, R_028878_SQ_PGM_RESOURCES_GS,
+ S_028878_NUM_GPRS(rshader->bc.ngpr) |
+ S_028878_STACK_SIZE(rshader->bc.nstack));
+ r600_store_context_reg(cb, R_028874_SQ_PGM_START_GS,
+ r600_resource_va(ctx->screen, (void *)shader->bo) >> 8);
+ /* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
+}
+
+
void evergreen_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
{
struct r600_command_buffer *cb = &shader->command_buffer;
@@ -3918,6 +4052,10 @@ void evergreen_init_state_functions(struct r600_context *rctx)
rctx->atoms[id++] = &rctx->b.streamout.begin_atom;
r600_init_atom(rctx, &rctx->vertex_shader.atom, id++, r600_emit_shader, 23);
r600_init_atom(rctx, &rctx->pixel_shader.atom, id++, r600_emit_shader, 0);
+ r600_init_atom(rctx, &rctx->geometry_shader.atom, id++, r600_emit_shader, 0);
+ r600_init_atom(rctx, &rctx->export_shader.atom, id++, r600_emit_shader, 0);
+ r600_init_atom(rctx, &rctx->shader_stages.atom, id++, evergreen_emit_shader_stages, 6);
+ r600_init_atom(rctx, &rctx->gs_rings.atom, id++, evergreen_emit_gs_rings, 26);
rctx->b.b.create_blend_state = evergreen_create_blend_state;
rctx->b.b.create_depth_stencil_alpha_state = evergreen_create_dsa_state;