mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-05 23:10:30 +01:00
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:
parent
015e7e7724
commit
1c181a7eff
6 changed files with 110 additions and 174 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue