r300g: add WPOS
This commit is contained in:
parent
dc7f309f9c
commit
bf60eb3fec
|
@ -165,6 +165,28 @@ static const float * get_shader_constant(
|
|||
vec[3] = 0;
|
||||
break;
|
||||
|
||||
case RC_STATE_R300_VIEWPORT_SCALE:
|
||||
if (r300->rs_state->enable_vte) {
|
||||
vec[0] = r300->viewport_state->xscale;
|
||||
vec[1] = r300->viewport_state->yscale;
|
||||
vec[2] = r300->viewport_state->zscale;
|
||||
} else {
|
||||
vec[0] = 1;
|
||||
vec[1] = 1;
|
||||
vec[2] = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_STATE_R300_VIEWPORT_OFFSET:
|
||||
if (r300->rs_state->enable_vte) {
|
||||
vec[0] = r300->viewport_state->xoffset;
|
||||
vec[1] = r300->viewport_state->yoffset;
|
||||
vec[2] = r300->viewport_state->zoffset;
|
||||
} else {
|
||||
/* Zeros. */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
debug_printf("r300: Implementation error: "
|
||||
"Unknown RC_CONSTANT type %d\n", constant->u.State[0]);
|
||||
|
|
|
@ -63,6 +63,11 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
|
|||
fs_inputs->fog = i;
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
assert(index == 0);
|
||||
fs_inputs->wpos = i;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
@ -114,6 +119,9 @@ static void allocate_hardware_inputs(
|
|||
if (inputs->fog != ATTR_UNUSED) {
|
||||
allocate(mydata, inputs->fog, reg++);
|
||||
}
|
||||
if (inputs->wpos != ATTR_UNUSED) {
|
||||
allocate(mydata, inputs->wpos, reg++);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_compare_state(
|
||||
|
@ -144,6 +152,7 @@ static void r300_translate_fragment_shader(
|
|||
struct r300_fragment_shader* fs = r300->fs;
|
||||
struct r300_fragment_program_compiler compiler;
|
||||
struct tgsi_to_rc ttr;
|
||||
int wpos = fs->inputs.wpos;
|
||||
|
||||
/* Setup the compiler. */
|
||||
memset(&compiler, 0, sizeof(compiler));
|
||||
|
@ -171,6 +180,18 @@ static void r300_translate_fragment_shader(
|
|||
|
||||
fs->shadow_samplers = compiler.Base.Program.ShadowSamplers;
|
||||
|
||||
/**
|
||||
* Transform the program to support WPOS.
|
||||
*
|
||||
* Introduce a small fragment at the start of the program that will be
|
||||
* the only code that directly reads the WPOS input.
|
||||
* All other code pieces that reference that input will be rewritten
|
||||
* to read from a newly allocated temporary. */
|
||||
if (wpos != ATTR_UNUSED) {
|
||||
/* Moving the input to some other reg is not really necessary. */
|
||||
rc_transform_fragment_wpos(&compiler.Base, wpos, wpos, TRUE);
|
||||
}
|
||||
|
||||
/* Invoke the compiler */
|
||||
r3xx_compile_fragment_program(&compiler);
|
||||
if (compiler.Base.Error) {
|
||||
|
|
|
@ -40,6 +40,7 @@ struct r300_shader_semantics {
|
|||
int bcolor[ATTR_COLOR_COUNT];
|
||||
int generic[ATTR_GENERIC_COUNT];
|
||||
int fog;
|
||||
int wpos;
|
||||
};
|
||||
|
||||
static INLINE void r300_shader_semantics_reset(
|
||||
|
@ -50,6 +51,7 @@ static INLINE void r300_shader_semantics_reset(
|
|||
info->pos = ATTR_UNUSED;
|
||||
info->psize = ATTR_UNUSED;
|
||||
info->fog = ATTR_UNUSED;
|
||||
info->wpos = ATTR_UNUSED;
|
||||
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
info->color[i] = ATTR_UNUSED;
|
||||
|
|
|
@ -719,6 +719,9 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
|
|||
r300->dirty_state |= R300_NEW_RS_BLOCK;
|
||||
r300->dirty_state |= R300_NEW_SCISSOR;
|
||||
r300->dirty_state |= R300_NEW_VIEWPORT;
|
||||
if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
|
||||
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free rasterizer state. */
|
||||
|
@ -897,6 +900,9 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
|
|||
}
|
||||
|
||||
r300->dirty_state |= R300_NEW_VIEWPORT;
|
||||
if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
|
||||
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
|
||||
}
|
||||
}
|
||||
|
||||
static void r300_set_vertex_buffers(struct pipe_context* pipe,
|
||||
|
|
|
@ -410,6 +410,26 @@ 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. */
|
||||
rX00_rs_tex(rs, tex_count, tex_count, FALSE);
|
||||
|
||||
/* 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++;
|
||||
}
|
||||
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. */
|
||||
if (col_count == 0 && tex_count == 0) {
|
||||
rX00_rs_col(rs, 0, 0, TRUE);
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
#include "radeon_compiler.h"
|
||||
|
||||
#include "util/u_math.h"
|
||||
|
||||
/* Convert info about VS output semantics into r300_shader_semantics. */
|
||||
static void r300_shader_read_vs_outputs(
|
||||
struct tgsi_shader_info* info,
|
||||
|
@ -144,6 +146,13 @@ 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);
|
||||
}
|
||||
|
@ -195,6 +204,13 @@ static void r300_stream_locations_notcl(
|
|||
gen_count++;
|
||||
}
|
||||
|
||||
/* WPOS. */
|
||||
if (vs_outputs->wpos != ATTR_UNUSED) {
|
||||
assert(tabi < 16);
|
||||
stream_loc[tabi++] = 6 + gen_count;
|
||||
gen_count++;
|
||||
}
|
||||
|
||||
/* XXX magic */
|
||||
assert(gen_count <= 8);
|
||||
|
||||
|
@ -246,6 +262,33 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
|
|||
if (outputs->fog != ATTR_UNUSED) {
|
||||
c->code->outputs[outputs->fog] = reg++;
|
||||
}
|
||||
|
||||
/* WPOS. */
|
||||
if (outputs->wpos != ATTR_UNUSED) {
|
||||
c->code->outputs[outputs->wpos] = reg++;
|
||||
}
|
||||
}
|
||||
|
||||
static void r300_insert_wpos(struct r300_vertex_program_compiler* c,
|
||||
struct r300_shader_semantics* outputs)
|
||||
{
|
||||
int i, lastOutput = 0;
|
||||
|
||||
/* Find the max output index. */
|
||||
lastOutput = MAX2(lastOutput, outputs->psize);
|
||||
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
|
||||
lastOutput = MAX2(lastOutput, outputs->color[i]);
|
||||
lastOutput = MAX2(lastOutput, outputs->bcolor[i]);
|
||||
}
|
||||
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
|
||||
lastOutput = MAX2(lastOutput, outputs->generic[i]);
|
||||
}
|
||||
lastOutput = MAX2(lastOutput, outputs->fog);
|
||||
|
||||
/* Set WPOS after the last output. */
|
||||
lastOutput++;
|
||||
rc_copy_output(&c->Base, 0, lastOutput); /* out[lastOutput] = out[0]; */
|
||||
outputs->wpos = lastOutput;
|
||||
}
|
||||
|
||||
void r300_translate_vertex_shader(struct r300_context* r300,
|
||||
|
@ -253,11 +296,10 @@ 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);
|
||||
r300_shader_vap_output_fmt(&vs->outputs, vs->hwfmt);
|
||||
r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);
|
||||
|
||||
/* Setup the compiler */
|
||||
rc_init(&compiler.Base);
|
||||
|
@ -277,9 +319,17 @@ void r300_translate_vertex_shader(struct r300_context* r300,
|
|||
|
||||
r300_tgsi_to_rc(&ttr, vs->state.tokens);
|
||||
|
||||
compiler.RequiredOutputs = ~(~0 << vs->info.num_outputs);
|
||||
compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs+use_wpos));
|
||||
compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
|
||||
|
||||
/* Insert the WPOS output. */
|
||||
if (use_wpos) {
|
||||
r300_insert_wpos(&compiler, &vs->outputs);
|
||||
}
|
||||
|
||||
r300_shader_vap_output_fmt(&vs->outputs, vs->hwfmt);
|
||||
r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);
|
||||
|
||||
/* Invoke the compiler */
|
||||
r3xx_compile_vertex_program(&compiler);
|
||||
if (compiler.Base.Error) {
|
||||
|
|
Loading…
Reference in New Issue