* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Transformations:
* 1) If the secondary color output is present, the primary color must be
- * inserted before it.
+ * present too.
* 2) If any back-face color output is present, there must be all 4 color
* outputs and missing ones must be inserted.
* 3) Insert a trailing texcoord output containing a copy of POS, for WPOS.
boolean color_used[2];
boolean bcolor_used[2];
- boolean temp_used[128];
/* Index of the pos output, typically 0. */
unsigned pos_output;
boolean first_instruction;
/* End instruction processed? */
boolean end_instruction;
+
+ boolean temp_used[1024];
};
static void emit_temp(struct tgsi_transform_context *ctx, unsigned reg)
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.Interpolate = interp;
+ decl.Declaration.Interpolate = 1;
decl.Declaration.Semantic = TRUE;
decl.Semantic.Name = name;
decl.Semantic.Index = index;
decl.Range.First = decl.Range.Last = reg;
+ decl.Interp.Interpolate = interp;
ctx->emit_declaration(ctx, &decl);
++vsctx->num_outputs;
}
-static void insert_output(struct tgsi_transform_context *ctx,
- struct tgsi_full_declaration *before,
- unsigned name, unsigned index, unsigned interp)
+static void insert_output_before(struct tgsi_transform_context *ctx,
+ struct tgsi_full_declaration *before,
+ unsigned name, unsigned index, unsigned interp)
{
struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
unsigned i;
/* Make a place for the new output. */
- for (i = before->Range.First; i < Elements(vsctx->out_remap); i++) {
+ for (i = before->Range.First; i < ARRAY_SIZE(vsctx->out_remap); i++) {
++vsctx->out_remap[i];
}
/* Insert the new output. */
- emit_output(ctx, name, index, interp, before->Range.First);
+ emit_output(ctx, name, index, interp,
+ before->Range.First + vsctx->decl_shift);
++vsctx->decl_shift;
}
-static void insert_trailing_bcolor(struct tgsi_transform_context *ctx,
- struct tgsi_full_declaration *before)
+static void insert_output_after(struct tgsi_transform_context *ctx,
+ struct tgsi_full_declaration *after,
+ unsigned name, unsigned index, unsigned interp)
{
struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
+ unsigned i;
- /* If BCOLOR0 is used, make sure BCOLOR1 is present too. Otherwise
- * the rasterizer doesn't do the color selection correctly. */
- if (vsctx->bcolor_used[0] && !vsctx->bcolor_used[1]) {
- if (before) {
- insert_output(ctx, before, TGSI_SEMANTIC_BCOLOR, 1,
- TGSI_INTERPOLATE_LINEAR);
- } else {
- emit_output(ctx, TGSI_SEMANTIC_BCOLOR, 1,
- TGSI_INTERPOLATE_LINEAR, vsctx->num_outputs);
- }
- vsctx->bcolor_used[1] = TRUE;
+ /* Make a place for the new output. */
+ for (i = after->Range.First+1; i < ARRAY_SIZE(vsctx->out_remap); i++) {
+ ++vsctx->out_remap[i];
}
+
+ /* Insert the new output. */
+ emit_output(ctx, name, index, interp,
+ after->Range.First + 1);
+
+ ++vsctx->decl_shift;
}
static void transform_decl(struct tgsi_transform_context *ctx,
case TGSI_SEMANTIC_COLOR:
assert(decl->Semantic.Index < 2);
- vsctx->color_used[decl->Semantic.Index] = TRUE;
/* We must rasterize the first color if the second one is
* used, otherwise the rasterizer doesn't do the color
* selection correctly. Declare it, but don't write to it. */
if (decl->Semantic.Index == 1 && !vsctx->color_used[0]) {
- insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
- TGSI_INTERPOLATE_LINEAR);
+ insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
+ TGSI_INTERPOLATE_LINEAR);
vsctx->color_used[0] = TRUE;
}
break;
case TGSI_SEMANTIC_BCOLOR:
assert(decl->Semantic.Index < 2);
- vsctx->bcolor_used[decl->Semantic.Index] = TRUE;
/* We must rasterize all 4 colors if back-face colors are
* used, otherwise the rasterizer doesn't do the color
* selection correctly. Declare it, but don't write to it. */
if (!vsctx->color_used[0]) {
- insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
- TGSI_INTERPOLATE_LINEAR);
+ insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
+ TGSI_INTERPOLATE_LINEAR);
vsctx->color_used[0] = TRUE;
}
if (!vsctx->color_used[1]) {
- insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 1,
- TGSI_INTERPOLATE_LINEAR);
+ insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 1,
+ TGSI_INTERPOLATE_LINEAR);
vsctx->color_used[1] = TRUE;
}
if (decl->Semantic.Index == 1 && !vsctx->bcolor_used[0]) {
- insert_output(ctx, decl, TGSI_SEMANTIC_BCOLOR, 0,
- TGSI_INTERPOLATE_LINEAR);
- vsctx->color_used[2] = TRUE;
+ insert_output_before(ctx, decl, TGSI_SEMANTIC_BCOLOR, 0,
+ TGSI_INTERPOLATE_LINEAR);
+ vsctx->bcolor_used[0] = TRUE;
}
- /* One more case is handled in insert_trailing_bcolor. */
break;
case TGSI_SEMANTIC_GENERIC:
break;
}
- if (decl->Semantic.Name != TGSI_SEMANTIC_BCOLOR) {
- /* Insert it as soon as possible. */
- insert_trailing_bcolor(ctx, decl);
- }
-
/* Since we're inserting new outputs in between, the following outputs
* should be moved to the right so that they don't overlap with
* the newly added ones. */
}
ctx->emit_declaration(ctx, decl);
+
+ /* Insert BCOLOR1 if needed. */
+ if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
+ decl->Semantic.Name == TGSI_SEMANTIC_BCOLOR &&
+ !vsctx->bcolor_used[1]) {
+ insert_output_after(ctx, decl, TGSI_SEMANTIC_BCOLOR, 1,
+ TGSI_INTERPOLATE_LINEAR);
+ }
}
static void transform_inst(struct tgsi_transform_context *ctx,
if (!vsctx->first_instruction) {
vsctx->first_instruction = TRUE;
- /* The trailing BCOLOR should be inserted before the code
- * if it hasn't already been done so. */
- insert_trailing_bcolor(ctx, NULL);
-
/* Insert the generic output for WPOS. */
emit_output(ctx, TGSI_SEMANTIC_GENERIC, vsctx->last_generic + 1,
TGSI_INTERPOLATE_PERSPECTIVE, vsctx->num_outputs);
/* Find a free temp for POSITION. */
- for (i = 0; i < Elements(vsctx->temp_used); i++) {
+ for (i = 0; i < ARRAY_SIZE(vsctx->temp_used); i++) {
if (!vsctx->temp_used[i]) {
emit_temp(ctx, i);
vsctx->pos_temp = i;
ctx->emit_instruction(ctx, inst);
}
-void r300_draw_init_vertex_shader(struct draw_context *draw,
+void r300_draw_init_vertex_shader(struct r300_context *r300,
struct r300_vertex_shader *vs)
{
+ struct draw_context *draw = r300->draw;
struct pipe_shader_state new_vs;
+ struct tgsi_shader_info info;
struct vs_transform_context transform;
const uint newLen = tgsi_num_tokens(vs->state.tokens) + 100 /* XXX */;
unsigned i;
+ tgsi_scan_shader(vs->state.tokens, &info);
+
new_vs.tokens = tgsi_alloc_tokens(newLen);
if (new_vs.tokens == NULL)
return;
memset(&transform, 0, sizeof(transform));
- for (i = 0; i < Elements(transform.out_remap); i++) {
+ for (i = 0; i < ARRAY_SIZE(transform.out_remap); i++) {
transform.out_remap[i] = i;
}
transform.last_generic = -1;
transform.base.transform_instruction = transform_inst;
transform.base.transform_declaration = transform_decl;
+ for (i = 0; i < info.num_outputs; i++) {
+ unsigned index = info.output_semantic_index[i];
+
+ switch (info.output_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ assert(index < 2);
+ transform.color_used[index] = TRUE;
+ break;
+
+ case TGSI_SEMANTIC_BCOLOR:
+ assert(index < 2);
+ transform.bcolor_used[index] = TRUE;
+ break;
+ }
+ }
+
tgsi_transform_shader(vs->state.tokens,
(struct tgsi_token*)new_vs.tokens,
newLen, &transform.base);
vs->state.tokens = new_vs.tokens;
/* Init the VS output table for the rasterizer. */
- r300_init_vs_outputs(vs);
+ r300_init_vs_outputs(r300, vs);
- /**/
+ /* Make the last generic be WPOS. */
+ vs->outputs.wpos = vs->outputs.generic[transform.last_generic + 1];
vs->outputs.generic[transform.last_generic + 1] = ATTR_UNUSED;
- vs->outputs.wpos -= 1;
}