FREE(r300->fb_state.state);
FREE(r300->rs_block_state.state);
FREE(r300->scissor_state.state);
- FREE(r300->vertex_format_state.state);
+ FREE(r300->vertex_stream_state.state);
+ FREE(r300->vap_output_state.state);
FREE(r300->viewport_state.state);
FREE(r300->ztop_state.state);
FREE(r300);
R300_INIT_ATOM(scissor_state, 3);
R300_INIT_ATOM(viewport_state, 9);
R300_INIT_ATOM(rs_block_state, 0);
- R300_INIT_ATOM(vertex_format_state, 26);
+ R300_INIT_ATOM(vertex_stream_state, 0);
+ R300_INIT_ATOM(vap_output_state, 6);
R300_INIT_ATOM(pvs_flush, 2);
R300_INIT_ATOM(vs_state, 0);
R300_INIT_ATOM(texture_cache_inval, 2);
r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state);
r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
- r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info);
+ r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
+ r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
}
uint32_t zb_format; /* R300_ZB_FORMAT */
};
+struct r300_vertex_stream_state {
+ /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
+ uint32_t vap_prog_stream_cntl[8];
+ /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
+ uint32_t vap_prog_stream_cntl_ext[8];
+
+ unsigned count;
+};
+
+struct r300_vap_output_state {
+ uint32_t vap_vtx_state_cntl; /* R300_VAP_VTX_STATE_CNTL: 0x2180 */
+ uint32_t vap_vsm_vtx_assm; /* R300_VAP_VSM_VTX_ASSM: 0x2184 */
+ uint32_t vap_out_vtx_fmt[2]; /* R300_VAP_OUTPUT_VTX_FMT_[0-1]: 0x2090 */
+};
+
struct r300_viewport_state {
float xscale; /* R300_VAP_VPORT_XSCALE: 0x2098 */
float xoffset; /* R300_VAP_VPORT_XOFFSET: 0x209c */
enum r300_buffer_tiling microtile, macrotile;
};
-struct r300_vertex_info {
- /* Parent class */
- struct vertex_info vinfo;
-
- /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
- uint32_t vap_prog_stream_cntl[8];
- /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
- uint32_t vap_prog_stream_cntl_ext[8];
-};
-
extern struct pipe_viewport_state r300_viewport_identity;
struct r300_context {
struct r300_query *query_current;
struct r300_query query_list;
- /* Vertex formatting information. */
- struct r300_atom vertex_format_state;
-
/* Various CSO state objects. */
/* Beginning of atom list. */
struct r300_atom atom_list;
/* Texture states. */
struct r300_texture* textures[8];
int texture_count;
+ /* Vertex stream formatting state. */
+ struct r300_atom vertex_stream_state;
+ /* VAP (vertex shader) output mapping state. */
+ struct r300_atom vap_output_state;
/* Vertex shader. */
struct r300_atom vs_state;
/* Viewport state. */
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
int vertex_element_count;
+ /* Vertex info for Draw. */
+ struct vertex_info vertex_info;
+
struct pipe_stencil_ref stencil_ref;
/* Bitmask of dirty state objects. */
END_CS;
}
-void r300_emit_vertex_format_state(struct r300_context* r300,
+void r300_emit_vertex_stream_state(struct r300_context* r300,
unsigned size, void* state)
{
- struct r300_vertex_info* vertex_info = (struct r300_vertex_info*)state;
+ struct r300_vertex_stream_state *streams =
+ (struct r300_vertex_stream_state*)state;
unsigned i;
CS_LOCALS(r300);
- DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n");
+ DBG(r300, DBG_DRAW, "r300: PSC emit:\n");
BEGIN_CS(size);
- OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_info->vinfo.size);
-
- OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
- OUT_CS(vertex_info->vinfo.hwfmt[0]);
- OUT_CS(vertex_info->vinfo.hwfmt[1]);
- OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
- OUT_CS(vertex_info->vinfo.hwfmt[2]);
- OUT_CS(vertex_info->vinfo.hwfmt[3]);
- for (i = 0; i < 4; i++) {
- DBG(r300, DBG_DRAW, " : hwfmt%d: 0x%08x\n", i,
- vertex_info->vinfo.hwfmt[i]);
- }
-
- OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);
- for (i = 0; i < 8; i++) {
- OUT_CS(vertex_info->vap_prog_stream_cntl[i]);
+ OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, streams->count);
+ for (i = 0; i < streams->count; i++) {
+ OUT_CS(streams->vap_prog_stream_cntl[i]);
DBG(r300, DBG_DRAW, " : prog_stream_cntl%d: 0x%08x\n", i,
- vertex_info->vap_prog_stream_cntl[i]);
+ streams->vap_prog_stream_cntl[i]);
}
- OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);
- for (i = 0; i < 8; i++) {
- OUT_CS(vertex_info->vap_prog_stream_cntl_ext[i]);
+ OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, streams->count);
+ for (i = 0; i < streams->count; i++) {
+ OUT_CS(streams->vap_prog_stream_cntl_ext[i]);
DBG(r300, DBG_DRAW, " : prog_stream_cntl_ext%d: 0x%08x\n", i,
- vertex_info->vap_prog_stream_cntl_ext[i]);
+ streams->vap_prog_stream_cntl_ext[i]);
}
END_CS;
}
+void r300_emit_vap_output_state(struct r300_context* r300,
+ unsigned size, void* state)
+{
+ struct r300_vap_output_state *vap_out_state =
+ (struct r300_vap_output_state*)state;
+ CS_LOCALS(r300);
+
+ DBG(r300, DBG_DRAW, "r300: VAP emit:\n");
+
+ BEGIN_CS(size);
+ OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
+ OUT_CS(vap_out_state->vap_vtx_state_cntl);
+ OUT_CS(vap_out_state->vap_vsm_vtx_assm);
+ OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
+ OUT_CS(vap_out_state->vap_out_vtx_fmt[0]);
+ OUT_CS(vap_out_state->vap_out_vtx_fmt[1]);
+ END_CS;
+}
+
void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state)
{
CS_LOCALS(r300);
void r300_emit_vertex_buffer(struct r300_context* r300);
-void r300_emit_vertex_format_state(struct r300_context* r300,
+void r300_emit_vertex_stream_state(struct r300_context* r300,
unsigned size, void* state);
+void r300_emit_vap_output_state(struct r300_context* r300,
+ unsigned size, void* state);
+
void r300_emit_vertex_program_code(struct r300_context* r300,
struct r300_vertex_program_code* code);
r300_update_derived_state(r300);
- return (struct vertex_info*)r300->vertex_format_state.state;
+ return &r300->vertex_info;
}
static boolean r300_render_allocate_vertices(struct vbuf_render* render,
r300->fs = fs;
r300_pick_fragment_shader(r300);
- r300->vertex_format_state.dirty = TRUE;
+ r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
+
+ if (r300->vs_state.state && r300_vertex_shader_setup_wpos(r300)) {
+ r300->vap_output_state.dirty = TRUE;
+ }
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}
if (r300->draw) {
draw_flush(r300->draw);
draw_set_vertex_buffers(r300->draw, count, buffers);
+ } else {
+ r300->vertex_stream_state.dirty = TRUE;
}
-
- r300->vertex_format_state.dirty = TRUE;
}
static boolean r300_validate_aos(struct r300_context *r300)
r300->vs_state.size = vs->code.length + 9;
r300->vs_state.dirty = TRUE;
- r300->vertex_format_state.dirty = TRUE;
+ r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
+ r300->vap_output_state.dirty = TRUE;
+ r300->vertex_stream_state.dirty = TRUE; /* XXX needed for TCL bypass */
r300->pvs_flush.dirty = TRUE;
if (r300->fs) {
output = draw_find_shader_output(r300->draw,
info->output_semantic_name[index],
info->output_semantic_index[index]);
- draw_emit_vertex_attr(
- (struct vertex_info*)r300->vertex_format_state.state,
- emit, interp, output);
+ draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output);
}
static void r300_draw_emit_all_attribs(struct r300_context* r300)
}
/* Update the PSC tables. */
+/* XXX move this function into r300_state.c after TCL-bypass gets removed
+ * XXX because this one is dependent only on vertex elements. */
static void r300_vertex_psc(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vertex_info *vformat =
- (struct r300_vertex_info*)r300->vertex_format_state.state;
+ struct r300_vertex_stream_state *vformat =
+ (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i;
int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int* stream_tab;
+ memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
+
/* If TCL is bypassed, map vertex streams to equivalent VS output
* locations. */
if (r300->tcl_bypass) {
}
vformat->vap_prog_stream_cntl[i >> 1] |=
(R300_LAST_VEC << (i & 1 ? 16 : 0));
+
+ vformat->count = (i >> 1) + 1;
+ r300->vertex_stream_state.size = (1 + vformat->count) * 2;
}
/* Update the PSC tables for SW TCL, using Draw. */
static void r300_swtcl_vertex_psc(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vertex_info *vformat =
- (struct r300_vertex_info*)r300->vertex_format_state.state;
- struct vertex_info* vinfo = &vformat->vinfo;
+ struct r300_vertex_stream_state *vformat =
+ (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
+ struct vertex_info* vinfo = &r300->vertex_info;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i, attrib_count;
int* vs_output_tab = vs->stream_loc_notcl;
+ memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
+
/* For each Draw attribute, route it to the fragment shader according
* to the vs_output_tab. */
attrib_count = vinfo->num_attribs;
}
vformat->vap_prog_stream_cntl[i >> 1] |=
(R300_LAST_VEC << (i & 1 ? 16 : 0));
+
+ vformat->count = (i >> 1) + 1;
+ r300->vertex_stream_state.size = (1 + vformat->count) * 2;
}
static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
{
struct r300_vertex_shader* vs = r300->vs_state.state;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
- struct r300_vertex_info *vformat =
- (struct r300_vertex_info*)r300->vertex_format_state.state;
- struct vertex_info* vinfo = &vformat->vinfo;
+ struct r300_vap_output_state *vap_out =
+ (struct r300_vap_output_state*)r300->vap_output_state.state;
- /* Mmm, delicious hax */
- memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info));
- memcpy(vinfo->hwfmt, vs->hwfmt, sizeof(uint)*4);
+ /* XXX Mmm, delicious hax */
+ memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
+ memcpy(vap_out, vs->hwfmt, sizeof(uint)*4);
r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs);
r300_vertex_psc(r300);
} else {
r300_draw_emit_all_attribs(r300);
- draw_compute_vertex_size(
- (struct vertex_info*)r300->vertex_format_state.state);
+ draw_compute_vertex_size(&r300->vertex_info);
r300_swtcl_vertex_psc(r300);
}
}
void r300_update_derived_state(struct r300_context* r300)
{
- /* XXX */
- if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER ||
- r300->vs_state.dirty || r300->vertex_format_state.dirty ||
- r300->rs_state.dirty) {
+ if (r300->rs_block_state.dirty ||
+ r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */
+ r300->rs_state.dirty) { /* XXX and remove this one (tcl_bypass dependency) */
r300_update_derived_shader_state(r300);
}