struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
struct r600_pipe_state *rstate = &shader->rstate;
struct r600_shader *rshader = &shader->shader;
- unsigned spi_vs_out_id[10];
- unsigned i, tmp, nparams;
+ unsigned spi_vs_out_id[10] = {};
+ unsigned i, tmp, nparams = 0;
/* clear previous register */
rstate->nregs = 0;
- /* so far never got proper semantic id from tgsi */
- for (i = 0; i < 10; i++) {
- spi_vs_out_id[i] = 0;
- }
- for (i = 0; i < 32; i++) {
- tmp = i << ((i & 3) * 8);
- spi_vs_out_id[i / 4] |= tmp;
+ for (i = 0; i < rshader->noutput; i++) {
+ if (rshader->output[i].spi_sid) {
+ tmp = rshader->output[i].spi_sid << ((nparams & 3) * 8);
+ spi_vs_out_id[nparams / 4] |= tmp;
+ nparams++;
+ }
}
+
for (i = 0; i < 10; i++) {
r600_pipe_state_add_reg(rstate,
R_02861C_SPI_VS_OUT_ID_0 + i * 4,
* VS is required to export at least one param and r600_shader_from_tgsi()
* takes care of adding a dummy export.
*/
- nparams = rshader->noutput - rshader->npos;
if (nparams < 1)
nparams = 1;
The compiler must issue the source argument to slots z, y, and x
*/
-
-int r600_find_vs_semantic_index(struct r600_shader *vs,
- struct r600_shader *ps, int id)
-{
- struct r600_shader_io *input = &ps->input[id];
- int index = 0;
-
- for (int i = 0; i < vs->noutput; i++) {
- if (input->name == vs->output[i].name &&
- input->sid == vs->output[i].sid)
- return index;
- else if (vs->output[i].name != TGSI_SEMANTIC_POSITION &&
- vs->output[i].name != TGSI_SEMANTIC_PSIZE)
- index++;
- }
- return 0;
-}
-
static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *shader)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
* DB_SOURCE_FORMAT - export control restrictions
*
*/
+
+
+/* Map name/sid pair from tgsi to the 8-bit semantic index for SPI setup */
+static int r600_spi_sid(struct r600_shader_io * io)
+{
+ int index, name = io->name;
+
+ /* These params are handled differently, they don't need
+ * semantic indices, so we'll use 0 for them.
+ */
+ if (name == TGSI_SEMANTIC_POSITION ||
+ name == TGSI_SEMANTIC_PSIZE ||
+ name == TGSI_SEMANTIC_FACE)
+ index = 0;
+ else {
+ if (name == TGSI_SEMANTIC_GENERIC) {
+ /* For generic params simply use sid from tgsi */
+ index = io->sid;
+ } else {
+
+ /* FIXME: two-side rendering is broken in r600g, this will
+ * keep old functionality */
+ if (name == TGSI_SEMANTIC_BCOLOR)
+ name = TGSI_SEMANTIC_COLOR;
+
+ /* For non-generic params - pack name and sid into 8 bits */
+ index = 0x80 | (name<<3) | (io->sid);
+ }
+
+ /* Make sure that all really used indices have nonzero value, so
+ * we can just compare it to 0 later instead of comparing the name
+ * with different values to detect special cases. */
+ index++;
+ }
+
+ return index;
+};
+
static int tgsi_declaration(struct r600_shader_ctx *ctx)
{
struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration;
i = ctx->shader->ninput++;
ctx->shader->input[i].name = d->Semantic.Name;
ctx->shader->input[i].sid = d->Semantic.Index;
+ ctx->shader->input[i].spi_sid = r600_spi_sid(&ctx->shader->input[i]);
ctx->shader->input[i].interpolate = d->Declaration.Interpolate;
ctx->shader->input[i].centroid = d->Declaration.Centroid;
ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + d->Range.First;
if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->bc->chip_class >= EVERGREEN) {
/* turn input into interpolate on EG */
- if (ctx->shader->input[i].name != TGSI_SEMANTIC_POSITION &&
- ctx->shader->input[i].name != TGSI_SEMANTIC_FACE) {
+ if (ctx->shader->input[i].spi_sid) {
ctx->shader->input[i].lds_pos = ctx->shader->nlds++;
if (ctx->shader->input[i].interpolate > 0) {
evergreen_interp_alu(ctx, i);
i = ctx->shader->noutput++;
ctx->shader->output[i].name = d->Semantic.Name;
ctx->shader->output[i].sid = d->Semantic.Index;
+ ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]);
ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + d->Range.First;
ctx->shader->output[i].interpolate = d->Declaration.Interpolate;
- if (ctx->type == TGSI_PROCESSOR_VERTEX) {
- /* these don't count as vertex param exports */
- if ((ctx->shader->output[i].name == TGSI_SEMANTIC_POSITION) ||
- (ctx->shader->output[i].name == TGSI_SEMANTIC_PSIZE))
- ctx->shader->npos++;
- }
break;
case TGSI_FILE_CONSTANT:
case TGSI_FILE_TEMPORARY:
struct r600_pipe_state *rstate = &shader->rstate;
struct r600_shader *rshader = &shader->shader;
unsigned spi_vs_out_id[10];
- unsigned i, tmp, nparams;
+ unsigned i, tmp, nparams = 0;
/* clear previous register */
rstate->nregs = 0;
- /* so far never got proper semantic id from tgsi */
- /* FIXME better to move this in config things so they get emited
- * only one time per cs
- */
- for (i = 0; i < 10; i++) {
- spi_vs_out_id[i] = 0;
- }
- for (i = 0; i < 32; i++) {
- tmp = i << ((i & 3) * 8);
- spi_vs_out_id[i / 4] |= tmp;
+ for (i = 0; i < rshader->noutput; i++) {
+ if (rshader->output[i].spi_sid) {
+ tmp = rshader->output[i].spi_sid << ((nparams & 3) * 8);
+ spi_vs_out_id[nparams / 4] |= tmp;
+ nparams++;
+ }
}
+
for (i = 0; i < 10; i++) {
r600_pipe_state_add_reg(rstate,
R_028614_SPI_VS_OUT_ID_0 + i * 4,
* VS is required to export at least one param and r600_shader_from_tgsi()
* takes care of adding a dummy export.
*/
- nparams = rshader->noutput - rshader->npos;
if (nparams < 1)
nparams = 1;