struct tgsi_interp_coef posCoef; /* For Z, W */
struct quad_header quad;
- uint firstFpInput; /** Semantic type of first frag input */
-
struct {
int left[2]; /**< [0] = row0, [1] = row1 */
int right[2];
*/
static void setup_tri_coefficients( struct setup_stage *setup )
{
- const enum interp_mode *interp;
-#define USE_INPUT_MAP 01
-#if USE_INPUT_MAP
- const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
-#endif
+ const struct softpipe_context *softpipe = setup->softpipe;
+ const struct pipe_shader_state *fs = &softpipe->fs->shader;
uint fragSlot;
- if (setup->softpipe->vertex_info.format[0] == FORMAT_HEADER) {
- /* skip header, pos slots */
- interp = setup->softpipe->vertex_info.interp_mode + 2;
- }
- else {
- /* skip pos slot */
- interp = setup->softpipe->vertex_info.interp_mode + 1;
- }
-
/* z and w are done by linear interpolation:
*/
tri_linear_coeff(setup, &setup->posCoef, 0, 2);
/* setup interpolation for all the remaining attributes:
*/
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
-#if !USE_INPUT_MAP
- uint vertSlot;
- if (setup->firstFpInput == TGSI_SEMANTIC_POSITION) {
- if (fragSlot == 0) {
- setup_fragcoord_coeff(setup);
- continue;
- }
- vertSlot = fragSlot;
- }
- else {
- vertSlot = fragSlot + 1;
- }
-
-#else
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
- /* XXX with a new INTERP_POSITION token, we could just add a
- * new case to the switch below.
- */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
-#endif
- uint j;
- switch (interp[fragSlot]) {
- case INTERP_CONSTANT:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- default:
- /* invalid interp mode */
- /* assert(0); re-enable this and run demos/fogcoord.c ... */
- ;
- }
- if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
- /* FOG.y = front/back facing XXX fix this */
- setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
- setup->coef[fragSlot].dadx[1] = 0.0;
- setup->coef[fragSlot].dady[1] = 0.0;
- }
-
-
-#if USE_INPUT_MAP
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
-#endif
}
}
static INLINE void
setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
{
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+ const struct softpipe_context *softpipe = setup->softpipe;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- unsigned fragSlot;
+ uint fragSlot;
/* use setup->vmin, vmax to point to vertices */
setup->vprovoke = prim->v[1];
/* setup interpolation for all the remaining attributes:
*/
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
+ assert(0); /* XXX fix this: */
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
- uint j;
- switch (interp[vertSlot]) {
- case INTERP_CONSTANT:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
-
- default:
- /* invalid interp mode */
- assert(0);
- }
+
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
}
}
setup_point(struct draw_stage *stage, struct prim_header *prim)
{
struct setup_stage *setup = setup_stage( stage );
- const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+ struct softpipe_context *softpipe = setup->softpipe;
+ const struct pipe_shader_state *fs = &softpipe->fs->shader;
const struct vertex_header *v0 = prim->v[0];
const int sizeAttr = setup->softpipe->psize_slot;
const float size
const_coeff(setup, &setup->posCoef, 0, 2);
const_coeff(setup, &setup->posCoef, 0, 3);
- for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
- /* which vertex output maps to this fragment input: */
- uint vertSlot = fs->input_map[fragSlot];
-
- if (vertSlot == 0) {
- /* special case: shader is reading gl_FragCoord */
+ for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+ uint j;
+
+ switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+ case INTERP_CONSTANT:
+ /* fall-through */
+ case INTERP_LINEAR:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_PERSPECTIVE:
+ for (j = 0; j < NUM_CHANNELS; j++)
+ point_persp_coeff(setup, setup->vprovoke,
+ &setup->coef[fragSlot], vertSlot, j);
+ break;
+ case INTERP_POS:
+ assert(fragSlot == 0);
+ assert(0); /* XXX fix this: */
setup_fragcoord_coeff(setup);
+ break;
+ default:
+ assert(0);
}
- else {
- uint j;
- switch (interp[vertSlot]) {
- case INTERP_CONSTANT:
- /* fall-through */
- case INTERP_LINEAR:
- for (j = 0; j < NUM_CHANNELS; j++)
- const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
- break;
- case INTERP_PERSPECTIVE:
- for (j = 0; j < NUM_CHANNELS; j++)
- point_persp_coeff(setup, setup->vprovoke,
- &setup->coef[fragSlot], vertSlot, j);
- break;
- default:
- assert(0);
- }
+
+ if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ /* FOG.y = front/back facing XXX fix this */
+ setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing;
+ setup->coef[fragSlot].dadx[1] = 0.0;
+ setup->coef[fragSlot].dady[1] = 0.0;
}
}
struct softpipe_context *sp = setup->softpipe;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
- setup->quad.nr_attrs = setup->softpipe->nr_frag_attrs;
-
- setup->firstFpInput = fs->input_semantic_name[0];
+ setup->quad.nr_attrs = fs->num_inputs;
sp->quad.first->begin(sp->quad.first);
}
/**
- * Determine which post-transform / pre-rasterization vertex attributes
- * we need.
- * Derived from: fs, setup states.
+ * Determine how to map vertex program outputs to fragment program inputs.
+ * Basically, this will be used when computing the triangle interpolation
+ * coefficients from the post-transform vertex attributes.
*/
static void calculate_vertex_layout( struct softpipe_context *softpipe )
{
const enum interp_mode colorInterp
= softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
struct vertex_info *vinfo = &softpipe->vertex_info;
+ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
uint i;
int src;
- memset(vinfo, 0, sizeof(*vinfo));
-
- softpipe->psize_slot = -1;
-
if (softpipe->vbuf) {
- /* softpipe's setup/rasterizer stage expects vertex to have a header */
- draw_emit_vertex_attr(vinfo, FORMAT_HEADER, INTERP_LINEAR, 0);
+ /* if using the post-transform vertex buffer, tell draw_vbuf to
+ * simply emit the whole post-xform vertex as-is:
+ */
+ vinfo_vbuf->num_attribs = 0;
+ draw_emit_vertex_attr(vinfo_vbuf, FORMAT_HEADER, INTERP_NONE, 0);
+ for (i = 0; i < vs->num_outputs; i++) {
+ draw_emit_vertex_attr(vinfo_vbuf, FORMAT_4F, INTERP_NONE, i);
+ }
+ draw_compute_vertex_size(vinfo_vbuf);
}
- /* always emit pos for softpipe rasterization */
- src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
- assert(src >= 0);
- draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src);
-
/*
- * XXX I think we need to reconcile the vertex shader outputs with
- * the fragment shader inputs here to make sure the slots line up.
- * Might just be getting lucky so far.
- * Or maybe do that in the state tracker?
+ * Loop over fragment shader inputs, searching for the matching output
+ * from the vertex shader.
*/
-
+ vinfo->num_attribs = 0;
for (i = 0; i < fs->num_inputs; i++) {
switch (fs->input_semantic_name[i]) {
-
case TGSI_SEMANTIC_POSITION:
- /* handled above */
+ src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+ assert(src >= 0);
+ draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_POS, src);
break;
case TGSI_SEMANTIC_COLOR:
}
}
- src = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
- if (src >= 0) {
- softpipe->psize_slot = src;
- draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_CONSTANT, src);
+ softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
+ if (softpipe->psize_slot >= 0) {
+ draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_CONSTANT,
+ softpipe->psize_slot);
}
-
draw_compute_vertex_size(vinfo);
-
- softpipe->nr_frag_attrs = fs->num_inputs;
}
*/
void softpipe_update_derived( struct softpipe_context *softpipe )
{
- if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS | SP_NEW_VS))
+ if (softpipe->dirty & (SP_NEW_RASTERIZER |
+ SP_NEW_FS |
+ SP_NEW_VS))
calculate_vertex_layout( softpipe );
if (softpipe->dirty & (SP_NEW_SCISSOR |