mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 23:18:20 +02:00
r300g: disable the rasterization of WPOS if it's unused by the FS
This commit is contained in:
parent
bf60eb3fec
commit
26f67a272b
4 changed files with 58 additions and 34 deletions
|
|
@ -556,6 +556,10 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
|
|||
r300->fs = fs;
|
||||
r300_pick_fragment_shader(r300);
|
||||
|
||||
if (r300->vs && r300_vertex_shader_setup_wpos(r300)) {
|
||||
r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
|
||||
}
|
||||
|
||||
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
|
||||
}
|
||||
|
||||
|
|
@ -974,7 +978,13 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
|
|||
}
|
||||
|
||||
r300->vs = vs;
|
||||
r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;
|
||||
if (r300->fs) {
|
||||
r300_vertex_shader_setup_wpos(r300);
|
||||
}
|
||||
|
||||
r300->dirty_state |=
|
||||
R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS |
|
||||
R300_NEW_VERTEX_FORMAT;
|
||||
} else {
|
||||
draw_flush(r300->draw);
|
||||
draw_bind_vertex_shader(r300->draw,
|
||||
|
|
|
|||
|
|
@ -411,23 +411,13 @@ static void r300_update_rs_block(struct r300_context* r300,
|
|||
}
|
||||
|
||||
/* Rasterize WPOS. */
|
||||
if (vs_outputs->wpos != ATTR_UNUSED) {
|
||||
/* Always rasterize if it's written by the VS,
|
||||
* otherwise it locks up. */
|
||||
/* If the FS doesn't need it, it's not written by the VS. */
|
||||
if (fs_inputs->wpos != ATTR_UNUSED) {
|
||||
rX00_rs_tex(rs, tex_count, tex_count, FALSE);
|
||||
rX00_rs_tex_write(rs, tex_count, fp_offset);
|
||||
|
||||
/* Write it to the FS input register if it's used by the FS. */
|
||||
if (fs_inputs->wpos != ATTR_UNUSED) {
|
||||
rX00_rs_tex_write(rs, tex_count, fp_offset);
|
||||
fp_offset++;
|
||||
}
|
||||
fp_offset++;
|
||||
tex_count++;
|
||||
} else {
|
||||
/* Skip the FS input register, leave it uninitialized. */
|
||||
/* If we try to set it to (0,0,0,1), it will lock up. */
|
||||
if (fs_inputs->wpos != ATTR_UNUSED) {
|
||||
fp_offset++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Rasterize at least one color, or bad things happen. */
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#include "r300_vs.h"
|
||||
#include "r300_fs.h"
|
||||
|
||||
#include "r300_context.h"
|
||||
#include "r300_screen.h"
|
||||
|
|
@ -90,10 +91,10 @@ static void r300_shader_read_vs_outputs(
|
|||
}
|
||||
}
|
||||
|
||||
static void r300_shader_vap_output_fmt(
|
||||
struct r300_shader_semantics* vs_outputs,
|
||||
uint* hwfmt)
|
||||
static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs)
|
||||
{
|
||||
struct r300_shader_semantics* vs_outputs = &vs->outputs;
|
||||
uint32_t* hwfmt = vs->hwfmt;
|
||||
int i, gen_count;
|
||||
|
||||
/* Do the actual vertex_info setup.
|
||||
|
|
@ -146,15 +147,11 @@ static void r300_shader_vap_output_fmt(
|
|||
gen_count++;
|
||||
}
|
||||
|
||||
/* WPOS. */
|
||||
if (vs_outputs->wpos != ATTR_UNUSED) {
|
||||
hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
|
||||
hwfmt[3] |= (4 << (3 * gen_count));
|
||||
gen_count++;
|
||||
}
|
||||
|
||||
/* XXX magic */
|
||||
assert(gen_count <= 8);
|
||||
|
||||
/* WPOS. */
|
||||
vs->wpos_tex_output = gen_count;
|
||||
}
|
||||
|
||||
/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed
|
||||
|
|
@ -211,9 +208,6 @@ static void r300_stream_locations_notcl(
|
|||
gen_count++;
|
||||
}
|
||||
|
||||
/* XXX magic */
|
||||
assert(gen_count <= 8);
|
||||
|
||||
for (; tabi < 16;) {
|
||||
stream_loc[tabi++] = -1;
|
||||
}
|
||||
|
|
@ -296,7 +290,6 @@ void r300_translate_vertex_shader(struct r300_context* r300,
|
|||
{
|
||||
struct r300_vertex_program_compiler compiler;
|
||||
struct tgsi_to_rc ttr;
|
||||
boolean use_wpos = TRUE;
|
||||
|
||||
/* Initialize. */
|
||||
r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
|
||||
|
|
@ -319,15 +312,13 @@ void r300_translate_vertex_shader(struct r300_context* r300,
|
|||
|
||||
r300_tgsi_to_rc(&ttr, vs->state.tokens);
|
||||
|
||||
compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs+use_wpos));
|
||||
compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs+1));
|
||||
compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
|
||||
|
||||
/* Insert the WPOS output. */
|
||||
if (use_wpos) {
|
||||
r300_insert_wpos(&compiler, &vs->outputs);
|
||||
}
|
||||
r300_insert_wpos(&compiler, &vs->outputs);
|
||||
|
||||
r300_shader_vap_output_fmt(&vs->outputs, vs->hwfmt);
|
||||
r300_shader_vap_output_fmt(vs);
|
||||
r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);
|
||||
|
||||
/* Invoke the compiler */
|
||||
|
|
@ -342,3 +333,30 @@ void r300_translate_vertex_shader(struct r300_context* r300,
|
|||
rc_destroy(&compiler.Base);
|
||||
vs->translated = TRUE;
|
||||
}
|
||||
|
||||
boolean r300_vertex_shader_setup_wpos(struct r300_context* r300)
|
||||
{
|
||||
struct r300_vertex_shader* vs = r300->vs;
|
||||
int tex_output = r300->vs->wpos_tex_output;
|
||||
uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output;
|
||||
uint32_t* hwfmt = vs->hwfmt;
|
||||
|
||||
if (r300->fs->inputs.wpos != ATTR_UNUSED) {
|
||||
/* Enable WPOS in VAP. */
|
||||
if (!(hwfmt[1] & tex_fmt)) {
|
||||
hwfmt[1] |= tex_fmt;
|
||||
hwfmt[3] |= (4 << (3 * tex_output));
|
||||
|
||||
assert(tex_output < 8);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
/* Disable WPOS in VAP. */
|
||||
if (hwfmt[1] & tex_fmt) {
|
||||
hwfmt[1] &= ~tex_fmt;
|
||||
hwfmt[3] &= ~(4 << (3 * tex_output));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ struct r300_vertex_shader {
|
|||
/* Stream locations for SWTCL or if TCL is bypassed. */
|
||||
int stream_loc_notcl[16];
|
||||
|
||||
/* Output stream location for WPOS. */
|
||||
int wpos_tex_output;
|
||||
|
||||
/* Has this shader been translated yet? */
|
||||
boolean translated;
|
||||
|
||||
|
|
@ -53,4 +56,7 @@ struct r300_vertex_shader {
|
|||
void r300_translate_vertex_shader(struct r300_context* r300,
|
||||
struct r300_vertex_shader* vs);
|
||||
|
||||
/* Return TRUE if VAP (hwfmt) needs to be re-emitted. */
|
||||
boolean r300_vertex_shader_setup_wpos(struct r300_context* r300);
|
||||
|
||||
#endif /* R300_VS_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue