r300g: Begin separating HW TCL and SW TCL state and setup.

This patch removes draw_context entirely from the HW TCL path and cleans up
a few other things along the way. Hopefully, nothing got broken.

Thanks to Marek Olšák for testing, review, and pointing out my bugs. :3
This commit is contained in:
Corbin Simpson 2009-11-15 05:25:15 +01:00
parent 015e7e7724
commit 1c181a7eff
6 changed files with 110 additions and 174 deletions

View file

@ -123,15 +123,24 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.clear = r300_clear;
if (r300screen->caps->has_tcl)
{
if (r300screen->caps->has_tcl) {
r300->context.draw_arrays = r300_draw_arrays;
r300->context.draw_elements = r300_draw_elements;
r300->context.draw_range_elements = r300_draw_range_elements;
}
else
{
assert(0);
} else {
r300->context.draw_arrays = r300_swtcl_draw_arrays;
r300->context.draw_elements = r300_draw_elements;
r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
/* Create a Draw. This is used for SW TCL. */
r300->draw = draw_create();
/* Enable our renderer. */
draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
/* Enable Draw's clipping. */
draw_set_driver_clipping(r300->draw, FALSE);
/* Force Draw to never do viewport transform, since we can do
* transform in hardware, always. */
draw_set_viewport_state(r300->draw, &r300_viewport_identity);
}
r300->context.is_texture_referenced = r300_is_texture_referenced;
@ -145,16 +154,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
r300->viewport_state = CALLOC_STRUCT(r300_viewport_state);
/* Create a Draw. This is used for vert collation and SW TCL. */
r300->draw = draw_create();
/* Enable our renderer. */
draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
/* Disable Draw's clipping if TCL is present. */
draw_set_driver_clipping(r300->draw, r300_screen(screen)->caps->has_tcl);
/* Force Draw to never do viewport transform, since (again) we can do
* transform in hardware, always. */
draw_set_viewport_state(r300->draw, &r300_viewport_identity);
/* Open up the OQ BO. */
r300->oqbo = screen->buffer_create(screen, 4096,
PIPE_BUFFER_USAGE_VERTEX, 4096);

View file

@ -183,8 +183,6 @@ boolean r300_draw_range_elements(struct pipe_context* pipe,
return FALSE;
}
setup_vertex_attributes(r300);
setup_index_buffer(r300, indexBuffer, indexSize);
r300_emit_dirty_state(r300);
@ -226,8 +224,6 @@ boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
return FALSE;
}
setup_vertex_attributes(r300);
r300_emit_dirty_state(r300);
r300_emit_aos(r300, start);

View file

@ -714,9 +714,6 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
tgsi_scan_shader(shader->tokens, &vs->info);
/* Appease Draw. */
vs->draw = draw_create_vertex_shader(r300->draw, shader);
return (void*)vs;
} else {
return draw_create_vertex_shader(r300->draw, shader);
@ -727,8 +724,6 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
draw_flush(r300->draw);
if (r300_screen(pipe->screen)->caps->has_tcl) {
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
@ -739,10 +734,10 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
r300_translate_vertex_shader(r300, vs);
}
draw_bind_vertex_shader(r300->draw, vs->draw);
r300->vs = vs;
r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;
} else {
draw_flush(r300->draw);
draw_bind_vertex_shader(r300->draw,
(struct draw_vertex_shader*)shader);
}
@ -756,7 +751,6 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
rc_constants_destroy(&vs->code.constants);
draw_delete_vertex_shader(r300->draw, vs->draw);
FREE((void*)vs->state.tokens);
FREE(shader);
} else {

View file

@ -65,84 +65,43 @@ int r300_shader_key_compare(void* key1, void* key2) {
static void r300_vs_tab_routes(struct r300_context* r300,
struct r300_vertex_info* vformat)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct vertex_info* vinfo = &vformat->vinfo;
int* tab = vformat->vs_tab;
boolean pos = FALSE, psize = FALSE, fog = FALSE;
int i, texs = 0, cols = 0;
struct tgsi_shader_info* info;
struct tgsi_shader_info* info = &r300->fs->info;
if (r300screen->caps->has_tcl) {
/* Use vertex shader to determine required routes. */
info = &r300->vs->info;
} else {
/* Use fragment shader to determine required routes. */
info = &r300->fs->info;
}
/* XXX One day we should figure out how to handle a different number of
* VS outputs and FS inputs, as well as a different number of vertex streams
* and VS inputs. It's definitely one of the sources of hardlocks. */
assert(info->num_inputs <= 16);
if (!r300screen->caps->has_tcl || !r300->rs_state->enable_vte)
{
for (i = 0; i < info->num_inputs; i++) {
switch (r300->vs->code.inputs[i]) {
case TGSI_SEMANTIC_POSITION:
pos = TRUE;
tab[i] = 0;
break;
case TGSI_SEMANTIC_COLOR:
tab[i] = 2 + cols;
cols++;
break;
case TGSI_SEMANTIC_PSIZE:
assert(psize == FALSE);
psize = TRUE;
tab[i] = 15;
break;
case TGSI_SEMANTIC_FOG:
assert(fog == FALSE);
fog = TRUE;
/* Fall through */
case TGSI_SEMANTIC_GENERIC:
tab[i] = 6 + texs;
texs++;
break;
default:
debug_printf("r300: Unknown vertex input %d\n",
info->input_semantic_name[i]);
break;
}
}
}
else
{
/* Just copy vert attribs over as-is. */
for (i = 0; i < info->num_inputs; i++) {
tab[i] = i;
}
for (i = 0; i < info->num_outputs; i++) {
switch (info->output_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
pos = TRUE;
break;
case TGSI_SEMANTIC_COLOR:
cols++;
break;
case TGSI_SEMANTIC_PSIZE:
psize = TRUE;
break;
case TGSI_SEMANTIC_FOG:
fog = TRUE;
/* Fall through */
case TGSI_SEMANTIC_GENERIC:
texs++;
break;
default:
debug_printf("r300: Unknown vertex output %d\n",
info->output_semantic_name[i]);
break;
}
for (i = 0; i < info->num_inputs; i++) {
switch (info->input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
pos = TRUE;
tab[i] = 0;
break;
case TGSI_SEMANTIC_COLOR:
tab[i] = 2 + cols;
cols++;
break;
case TGSI_SEMANTIC_PSIZE:
assert(psize == FALSE);
psize = TRUE;
tab[i] = 15;
break;
case TGSI_SEMANTIC_FOG:
assert(fog == FALSE);
fog = TRUE;
/* Fall through */
case TGSI_SEMANTIC_GENERIC:
tab[i] = 6 + texs;
texs++;
break;
default:
debug_printf("r300: Unknown vertex input %d\n",
info->input_semantic_name[i]);
break;
}
}
@ -161,8 +120,7 @@ static void r300_vs_tab_routes(struct r300_context* r300,
/* We need to add vertex position attribute only for SW TCL case,
* for HW TCL case it could be generated by vertex shader */
if (!pos && !r300screen->caps->has_tcl) {
debug_printf("r300: Forcing vertex position attribute emit...\n");
if (!pos) {
/* Make room for the position attribute
* at the beginning of the tab. */
for (i = 15; i > 0; i--) {
@ -230,29 +188,64 @@ static void r300_vs_tab_routes(struct r300_context* r300,
static void r300_vertex_psc(struct r300_context* r300,
struct r300_vertex_info* vformat)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
uint16_t type, swizzle;
enum pipe_format format;
unsigned i;
/* Vertex shaders have no semantics on their inputs,
* so PSC should just route stuff based on the vertex elements,
* and not on attrib information. */
DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements"
" in psc\n",
r300->vs->info.num_inputs,
r300->vertex_element_count);
for (i = 0; i < r300->vertex_element_count; i++) {
format = r300->vertex_element[i].src_format;
type = r300_translate_vertex_data_type(format) |
(i << R300_DST_VEC_LOC_SHIFT);
swizzle = r300_translate_vertex_data_swizzle(format);
if (i % 2) {
vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
} else {
vformat->vap_prog_stream_cntl[i >> 1] |= type;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
}
}
assert(i <= 15);
/* Set the last vector in the PSC. */
if (i) {
i -= 1;
}
vformat->vap_prog_stream_cntl[i >> 1] |=
(R300_LAST_VEC << (i & 1 ? 16 : 0));
}
/* Update the PSC tables for SW TCL, using Draw. */
static void r300_swtcl_vertex_psc(struct r300_context* r300,
struct r300_vertex_info* vformat)
{
struct vertex_info* vinfo = &vformat->vinfo;
int* tab = vformat->vs_tab;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i, attrib_count;
/* Vertex shaders have no semantics on their inputs,
* so PSC should just route stuff based on their info,
* and not on attrib information. */
if (r300screen->caps->has_tcl) {
attrib_count = r300->vs->info.num_inputs;
DBG(r300, DBG_DRAW, "r300: routing %d attribs in psc for vs\n",
attrib_count);
} else {
attrib_count = vinfo->num_attribs;
DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
for (i = 0; i < attrib_count; i++) {
DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
" tab %d\n", vinfo->attrib[i].src_index,
vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
tab[i]);
}
/* For each Draw attribute, route it to the fragment shader according
* to the tab. */
attrib_count = vinfo->num_attribs;
DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
for (i = 0; i < attrib_count; i++) {
DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
" tab %d\n", vinfo->attrib[i].src_index,
vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
tab[i]);
}
for (i = 0; i < attrib_count; i++) {
@ -272,12 +265,10 @@ static void r300_vertex_psc(struct r300_context* r300,
/* Add the attribute to the PSC table. */
if (i & 1) {
vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
} else {
vformat->vap_prog_stream_cntl[i >> 1] |= type << 0;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 0;
vformat->vap_prog_stream_cntl[i >> 1] |= type;
vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
}
}
@ -505,7 +496,13 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
}
r300_vs_tab_routes(r300, vformat);
r300_vertex_psc(r300, vformat);
if (r300screen->caps->has_tcl) {
r300_vertex_psc(r300, vformat);
} else {
r300_swtcl_vertex_psc(r300, vformat);
}
r300_update_fs_tab(r300, vformat);
r300_update_rs_block(r300, rs_block);
@ -553,8 +550,7 @@ static void r300_update_ztop(struct r300_context* r300)
void r300_update_derived_state(struct r300_context* r300)
{
/* XXX */
if (TRUE || r300->dirty_state &
if (r300->dirty_state &
(R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) {
r300_update_derived_shader_state(r300);
}

View file

@ -34,52 +34,6 @@
#include "r300_reg.h"
#include "r300_winsys.h"
static INLINE void setup_vertex_attribute(struct r300_vertex_info *vinfo,
struct pipe_vertex_element *vert_elem,
unsigned attr_num)
{
uint16_t hw_fmt1, hw_fmt2;
hw_fmt1 = r300_translate_vertex_data_type(vert_elem->src_format) |
(attr_num << R300_DST_VEC_LOC_SHIFT);
hw_fmt2 = r300_translate_vertex_data_swizzle(vert_elem->src_format);
if (attr_num % 2 == 0)
{
vinfo->vap_prog_stream_cntl[attr_num >> 1] = hw_fmt1;
vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] = hw_fmt2;
}
else
{
vinfo->vap_prog_stream_cntl[attr_num >> 1] |= hw_fmt1 << 16;
vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] |= hw_fmt2 << 16;
}
}
static void finish_vertex_attribs_setup(struct r300_vertex_info *vinfo,
unsigned attribs_num)
{
uint32_t last_vec_bit = (attribs_num % 2 == 0) ?
(R300_LAST_VEC << 16) : R300_LAST_VEC;
assert(attribs_num > 0 && attribs_num <= 16);
vinfo->vap_prog_stream_cntl[(attribs_num - 1) >> 1] |= last_vec_bit;
}
void setup_vertex_attributes(struct r300_context *r300)
{
struct pipe_vertex_element *vert_elem;
int i;
for (i = 0; i < r300->vertex_element_count; i++) {
vert_elem = &r300->vertex_element[i];
setup_vertex_attribute(r300->vertex_info, vert_elem, i);
}
finish_vertex_attribs_setup(r300->vertex_info,
r300->vertex_element_count);
}
static INLINE int get_buffer_offset(struct r300_context *r300,
unsigned int buf_nr,
unsigned int elem_offset)

View file

@ -35,9 +35,6 @@ struct r300_vertex_shader {
struct pipe_shader_state state;
struct tgsi_shader_info info;
/* Fallback shader, because Draw has issues */
struct draw_vertex_shader* draw;
/* Has this shader been translated yet? */
boolean translated;