gallium/ttn: Convert to using VARYING_SLOT_* / FRAG_RESULT_*.

This avoids exceeding the size of the .index bitfield since it got
truncated, and should make our NIR look more like the NIR that the rest of
the NIR developers are working on.

v2: split out vc4 updates, first patch uses varying_slot_to_tgsi_semantic()
    helper, and second patch does the actual conversion.
v3: add frag_result_to_tgsi_semantic() helper and don't try to map
    frag_results to semantic name/index as if they were varying_slot's
v4: use VERT_ATTRIB_ for VS inputs
v5: Fix vc4 build.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
Eric Anholt 2015-08-04 14:28:02 -07:00
parent 7a275fcda8
commit 8fd3e53f3d
6 changed files with 238 additions and 46 deletions

View File

@ -94,6 +94,128 @@ struct ttn_compile {
#define ttn_channel(b, src, swiz) \
nir_swizzle(b, src, SWIZ(swiz, swiz, swiz, swiz), 1, false)
static gl_varying_slot
tgsi_varying_semantic_to_slot(unsigned semantic, unsigned index)
{
switch (semantic) {
case TGSI_SEMANTIC_POSITION:
return VARYING_SLOT_POS;
case TGSI_SEMANTIC_COLOR:
if (index == 0)
return VARYING_SLOT_COL0;
else
return VARYING_SLOT_COL1;
case TGSI_SEMANTIC_BCOLOR:
if (index == 0)
return VARYING_SLOT_BFC0;
else
return VARYING_SLOT_BFC1;
case TGSI_SEMANTIC_FOG:
return VARYING_SLOT_FOGC;
case TGSI_SEMANTIC_PSIZE:
return VARYING_SLOT_PSIZ;
case TGSI_SEMANTIC_GENERIC:
return VARYING_SLOT_VAR0 + index;
case TGSI_SEMANTIC_FACE:
return VARYING_SLOT_FACE;
case TGSI_SEMANTIC_EDGEFLAG:
return VARYING_SLOT_EDGE;
case TGSI_SEMANTIC_PRIMID:
return VARYING_SLOT_PRIMITIVE_ID;
case TGSI_SEMANTIC_CLIPDIST:
if (index == 0)
return VARYING_SLOT_CLIP_DIST0;
else
return VARYING_SLOT_CLIP_DIST1;
case TGSI_SEMANTIC_CLIPVERTEX:
return VARYING_SLOT_CLIP_VERTEX;
case TGSI_SEMANTIC_TEXCOORD:
return VARYING_SLOT_TEX0 + index;
case TGSI_SEMANTIC_PCOORD:
return VARYING_SLOT_PNTC;
case TGSI_SEMANTIC_VIEWPORT_INDEX:
return VARYING_SLOT_VIEWPORT;
case TGSI_SEMANTIC_LAYER:
return VARYING_SLOT_LAYER;
default:
fprintf(stderr, "Bad TGSI semantic: %d/%d\n", semantic, index);
abort();
}
}
/* Temporary helper to remap back to TGSI style semantic name/index
* values, for use in drivers that haven't been converted to using
* VARYING_SLOT_
*/
void
varying_slot_to_tgsi_semantic(gl_varying_slot slot,
unsigned *semantic_name, unsigned *semantic_index)
{
static const unsigned map[][2] = {
[VARYING_SLOT_POS] = { TGSI_SEMANTIC_POSITION, 0 },
[VARYING_SLOT_COL0] = { TGSI_SEMANTIC_COLOR, 0 },
[VARYING_SLOT_COL1] = { TGSI_SEMANTIC_COLOR, 1 },
[VARYING_SLOT_BFC0] = { TGSI_SEMANTIC_BCOLOR, 0 },
[VARYING_SLOT_BFC1] = { TGSI_SEMANTIC_BCOLOR, 1 },
[VARYING_SLOT_FOGC] = { TGSI_SEMANTIC_FOG, 0 },
[VARYING_SLOT_PSIZ] = { TGSI_SEMANTIC_PSIZE, 0 },
[VARYING_SLOT_FACE] = { TGSI_SEMANTIC_FACE, 0 },
[VARYING_SLOT_EDGE] = { TGSI_SEMANTIC_EDGEFLAG, 0 },
[VARYING_SLOT_PRIMITIVE_ID] = { TGSI_SEMANTIC_PRIMID, 0 },
[VARYING_SLOT_CLIP_DIST0] = { TGSI_SEMANTIC_CLIPDIST, 0 },
[VARYING_SLOT_CLIP_DIST1] = { TGSI_SEMANTIC_CLIPDIST, 1 },
[VARYING_SLOT_CLIP_VERTEX] = { TGSI_SEMANTIC_CLIPVERTEX, 0 },
[VARYING_SLOT_PNTC] = { TGSI_SEMANTIC_PCOORD, 0 },
[VARYING_SLOT_VIEWPORT] = { TGSI_SEMANTIC_VIEWPORT_INDEX, 0 },
[VARYING_SLOT_LAYER] = { TGSI_SEMANTIC_LAYER, 0 },
};
if (slot >= VARYING_SLOT_VAR0) {
*semantic_name = TGSI_SEMANTIC_GENERIC;
*semantic_index = slot - VARYING_SLOT_VAR0;
return;
}
if (slot >= VARYING_SLOT_TEX0 && slot <= VARYING_SLOT_TEX7) {
*semantic_name = TGSI_SEMANTIC_TEXCOORD;
*semantic_index = slot - VARYING_SLOT_TEX0;
return;
}
if (slot >= ARRAY_SIZE(map)) {
fprintf(stderr, "Unknown varying slot %d\n", slot);
abort();
}
*semantic_name = map[slot][0];
*semantic_index = map[slot][1];
}
/* Temporary helper to remap back to TGSI style semantic name/index
* values, for use in drivers that haven't been converted to using
* FRAG_RESULT_
*/
void
frag_result_to_tgsi_semantic(gl_frag_result slot,
unsigned *semantic_name, unsigned *semantic_index)
{
static const unsigned map[][2] = {
[FRAG_RESULT_DEPTH] = { TGSI_SEMANTIC_POSITION, 0 },
[FRAG_RESULT_COLOR] = { TGSI_SEMANTIC_COLOR, -1 },
[FRAG_RESULT_DATA0 + 0] = { TGSI_SEMANTIC_COLOR, 0 },
[FRAG_RESULT_DATA0 + 1] = { TGSI_SEMANTIC_COLOR, 1 },
[FRAG_RESULT_DATA0 + 2] = { TGSI_SEMANTIC_COLOR, 2 },
[FRAG_RESULT_DATA0 + 3] = { TGSI_SEMANTIC_COLOR, 3 },
[FRAG_RESULT_DATA0 + 4] = { TGSI_SEMANTIC_COLOR, 4 },
[FRAG_RESULT_DATA0 + 5] = { TGSI_SEMANTIC_COLOR, 5 },
[FRAG_RESULT_DATA0 + 6] = { TGSI_SEMANTIC_COLOR, 6 },
[FRAG_RESULT_DATA0 + 7] = { TGSI_SEMANTIC_COLOR, 7 },
};
*semantic_name = map[slot][0];
*semantic_index = map[slot][1];
}
static nir_ssa_def *
ttn_src_for_dest(nir_builder *b, nir_alu_dest *dest)
{
@ -216,12 +338,15 @@ ttn_emit_declaration(struct ttn_compile *c)
var->data.mode = nir_var_shader_in;
var->name = ralloc_asprintf(var, "in_%d", idx);
/* We should probably translate to a VERT_ATTRIB_* or VARYING_SLOT_*
* instead, but nothing in NIR core is looking at the value
* currently, and this is less change to drivers.
*/
var->data.location = decl->Semantic.Name;
var->data.index = decl->Semantic.Index;
if (c->scan->processor == TGSI_PROCESSOR_FRAGMENT) {
var->data.location =
tgsi_varying_semantic_to_slot(decl->Semantic.Name,
decl->Semantic.Index);
} else {
assert(!decl->Declaration.Semantic);
var->data.location = VERT_ATTRIB_GENERIC0 + idx;
}
var->data.index = 0;
/* We definitely need to translate the interpolation field, because
* nir_print will decode it.
@ -241,6 +366,8 @@ ttn_emit_declaration(struct ttn_compile *c)
exec_list_push_tail(&b->shader->inputs, &var->node);
break;
case TGSI_FILE_OUTPUT: {
int semantic_name = decl->Semantic.Name;
int semantic_index = decl->Semantic.Index;
/* Since we can't load from outputs in the IR, we make temporaries
* for the outputs and emit stores to the real outputs at the end of
* the shader.
@ -252,14 +379,40 @@ ttn_emit_declaration(struct ttn_compile *c)
var->data.mode = nir_var_shader_out;
var->name = ralloc_asprintf(var, "out_%d", idx);
var->data.index = 0;
var->data.location = decl->Semantic.Name;
if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
decl->Semantic.Index == 0 &&
c->scan->properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
var->data.index = -1;
else
var->data.index = decl->Semantic.Index;
if (c->scan->processor == TGSI_PROCESSOR_FRAGMENT) {
switch (semantic_name) {
case TGSI_SEMANTIC_COLOR: {
/* TODO tgsi loses some information, so we cannot
* actually differentiate here between DSB and MRT
* at this point. But so far no drivers using tgsi-
* to-nir support dual source blend:
*/
bool dual_src_blend = false;
if (dual_src_blend && (semantic_index == 1)) {
var->data.location = FRAG_RESULT_DATA0;
var->data.index = 1;
} else {
if (c->scan->properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
var->data.location = FRAG_RESULT_COLOR;
else
var->data.location = FRAG_RESULT_DATA0 + semantic_index;
}
break;
}
case TGSI_SEMANTIC_POSITION:
var->data.location = FRAG_RESULT_DEPTH;
break;
default:
fprintf(stderr, "Bad TGSI semantic: %d/%d\n",
decl->Semantic.Name, decl->Semantic.Index);
abort();
}
} else {
var->data.location =
tgsi_varying_semantic_to_slot(semantic_name, semantic_index);
}
if (is_array) {
unsigned j;

View File

@ -28,3 +28,9 @@ struct nir_shader_compiler_options *options;
struct nir_shader *
tgsi_to_nir(const void *tgsi_tokens,
const struct nir_shader_compiler_options *options);
void
varying_slot_to_tgsi_semantic(gl_varying_slot slot,
unsigned *semantic_name, unsigned *semantic_index);
void
frag_result_to_tgsi_semantic(gl_frag_result slot,
unsigned *semantic_name, unsigned *semantic_index);

View File

@ -2133,17 +2133,12 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
struct ir3_shader_variant *so = ctx->so;
unsigned array_len = MAX2(glsl_get_length(in->type), 1);
unsigned ncomp = glsl_get_components(in->type);
/* XXX: map loc slots to semantics */
unsigned semantic_name = in->data.location;
unsigned semantic_index = in->data.index;
unsigned n = in->data.driver_location;
unsigned slot = in->data.location;
DBG("; in: %u:%u, len=%ux%u, loc=%u",
semantic_name, semantic_index, array_len,
ncomp, n);
DBG("; in: slot=%u, len=%ux%u, drvloc=%u",
slot, array_len, ncomp, n);
so->inputs[n].semantic =
ir3_semantic_name(semantic_name, semantic_index);
so->inputs[n].compmask = (1 << ncomp) - 1;
so->inputs[n].inloc = ctx->next_inloc;
so->inputs[n].interpolate = 0;
@ -2164,11 +2159,19 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
break;
}
for (int i = 0; i < ncomp; i++) {
struct ir3_instruction *instr = NULL;
unsigned idx = (n * 4) + i;
if (ctx->so->type == SHADER_FRAGMENT) {
unsigned semantic_name, semantic_index;
varying_slot_to_tgsi_semantic(slot,
&semantic_name, &semantic_index);
so->inputs[n].semantic =
ir3_semantic_name(semantic_name, semantic_index);
for (int i = 0; i < ncomp; i++) {
struct ir3_instruction *instr = NULL;
unsigned idx = (n * 4) + i;
if (ctx->so->type == SHADER_FRAGMENT) {
if (semantic_name == TGSI_SEMANTIC_POSITION) {
so->inputs[n].bary = false;
so->frag_coord = true;
@ -2208,11 +2211,17 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
instr = create_frag_input(ctx,
so->inputs[n].inloc + i - 8, use_ldlv);
}
} else {
instr = create_input(ctx->block, idx);
}
ctx->ir->inputs[idx] = instr;
ctx->ir->inputs[idx] = instr;
}
} else if (ctx->so->type == SHADER_VERTEX) {
so->inputs[n].semantic = 0;
for (int i = 0; i < ncomp; i++) {
unsigned idx = (n * 4) + i;
ctx->ir->inputs[idx] = create_input(ctx->block, idx);
}
} else {
compile_error(ctx, "unknown shader type: %d\n", ctx->so->type);
}
if (so->inputs[n].bary || (ctx->so->type == SHADER_VERTEX)) {
@ -2227,17 +2236,18 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)
struct ir3_shader_variant *so = ctx->so;
unsigned array_len = MAX2(glsl_get_length(out->type), 1);
unsigned ncomp = glsl_get_components(out->type);
/* XXX: map loc slots to semantics */
unsigned semantic_name = out->data.location;
unsigned semantic_index = out->data.index;
unsigned semantic_name, semantic_index;
unsigned n = out->data.driver_location;
unsigned slot = out->data.location;
unsigned comp = 0;
DBG("; out: %u:%u, len=%ux%u, loc=%u",
semantic_name, semantic_index, array_len,
ncomp, n);
DBG("; out: slot=%u, len=%ux%u, drvloc=%u",
slot, array_len, ncomp, n);
if (ctx->so->type == SHADER_VERTEX) {
varying_slot_to_tgsi_semantic(slot,
&semantic_name, &semantic_index);
switch (semantic_name) {
case TGSI_SEMANTIC_POSITION:
so->writes_pos = true;
@ -2255,7 +2265,10 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)
compile_error(ctx, "unknown VS semantic name: %s\n",
tgsi_semantic_names[semantic_name]);
}
} else {
} else if (ctx->so->type == SHADER_FRAGMENT) {
frag_result_to_tgsi_semantic(slot,
&semantic_name, &semantic_index);
switch (semantic_name) {
case TGSI_SEMANTIC_POSITION:
comp = 2; /* tgsi will write to .z component */
@ -2271,6 +2284,8 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)
compile_error(ctx, "unknown FS semantic name: %s\n",
tgsi_semantic_names[semantic_name]);
}
} else {
compile_error(ctx, "unknown shader type: %d\n", ctx->so->type);
}
compile_assert(ctx, n < ARRAY_SIZE(so->outputs));

View File

@ -38,6 +38,7 @@
#include "util/u_format.h"
#include "vc4_qir.h"
#include "glsl/nir/nir_builder.h"
#include "nir/tgsi_to_nir.h"
#include "vc4_context.h"
/** Emits a load of the previous fragment color from the tile buffer. */
@ -400,7 +401,10 @@ vc4_nir_lower_blend_block(nir_block *block, void *state)
}
}
assert(output_var);
unsigned semantic_name = output_var->data.location;
unsigned semantic_name, semantic_index;
varying_slot_to_tgsi_semantic(output_var->data.location,
&semantic_name, &semantic_index);
if (semantic_name != TGSI_SEMANTIC_COLOR)
continue;

View File

@ -22,6 +22,7 @@
*/
#include "vc4_qir.h"
#include "nir/tgsi_to_nir.h"
#include "tgsi/tgsi_info.h"
#include "glsl/nir/nir_builder.h"
@ -71,8 +72,11 @@ vc4_nir_lower_input(struct vc4_compile *c, nir_builder *b,
}
}
assert(input_var);
int semantic_name = input_var->data.location;
int semantic_index = input_var->data.index;
unsigned semantic_name, semantic_index;
varying_slot_to_tgsi_semantic(input_var->data.location,
&semantic_name, &semantic_index);
/* All TGSI-to-NIR inputs are vec4. */
assert(intr->num_components == 4);
@ -141,7 +145,10 @@ vc4_nir_lower_output(struct vc4_compile *c, nir_builder *b,
}
}
assert(output_var);
unsigned semantic_name = output_var->data.location;
unsigned semantic_name, semantic_index;
varying_slot_to_tgsi_semantic(output_var->data.location,
&semantic_name, &semantic_index);
if (c->stage == QSTAGE_COORD &&
(semantic_name != TGSI_SEMANTIC_POSITION &&

View File

@ -1412,11 +1412,12 @@ ntq_setup_inputs(struct vc4_compile *c)
for (unsigned i = 0; i < num_entries; i++) {
nir_variable *var = vars[i];
unsigned array_len = MAX2(glsl_get_length(var->type), 1);
/* XXX: map loc slots to semantics */
unsigned semantic_name = var->data.location;
unsigned semantic_index = var->data.index;
unsigned semantic_name, semantic_index;
unsigned loc = var->data.driver_location;
varying_slot_to_tgsi_semantic(var->data.location,
&semantic_name, &semantic_index);
assert(array_len == 1);
(void)array_len;
resize_qreg_array(c, &c->inputs, &c->inputs_array_size,
@ -1448,11 +1449,17 @@ ntq_setup_outputs(struct vc4_compile *c)
{
foreach_list_typed(nir_variable, var, node, &c->s->outputs) {
unsigned array_len = MAX2(glsl_get_length(var->type), 1);
/* XXX: map loc slots to semantics */
unsigned semantic_name = var->data.location;
unsigned semantic_index = var->data.index;
unsigned semantic_name, semantic_index;
unsigned loc = var->data.driver_location * 4;
if (c->stage == QSTAGE_FRAG) {
frag_result_to_tgsi_semantic(var->data.location,
&semantic_name, &semantic_index);
} else {
varying_slot_to_tgsi_semantic(var->data.location,
&semantic_name, &semantic_index);
}
assert(array_len == 1);
(void)array_len;