dst[0] = create_uniform(b, primitive_map + idx);
break;
+ case nir_intrinsic_load_gs_header_ir3:
+ dst[0] = ctx->gs_header;
+ break;
+
+ case nir_intrinsic_load_primitive_id:
+ dst[0] = ctx->primitive_id;
+ break;
+
case nir_intrinsic_load_ubo:
emit_intrinsic_load_ubo(ctx, intr, dst);
break;
unsigned frac = in->data.location_frac;
unsigned slot = in->data.location;
+ /* Inputs are loaded using ldlw or ldg for these stages. */
+ if (ctx->so->type == MESA_SHADER_TESS_CTRL ||
+ ctx->so->type == MESA_SHADER_TESS_EVAL ||
+ ctx->so->type == MESA_SHADER_GEOMETRY)
+ return;
+
/* skip unread inputs, we could end up with (for example), unsplit
* matrix/etc inputs in the case they are not read, so just silently
* skip these.
ir3_context_error(ctx, "unknown FS output name: %s\n",
gl_frag_result_name(slot));
}
- } else if (ctx->so->type == MESA_SHADER_VERTEX) {
+ } else if (ctx->so->type == MESA_SHADER_VERTEX ||
+ ctx->so->type == MESA_SHADER_GEOMETRY) {
switch (slot) {
case VARYING_SLOT_POS:
so->writes_pos = true;
case VARYING_SLOT_PSIZ:
so->writes_psize = true;
break;
+ case VARYING_SLOT_PRIMITIVE_ID:
+ case VARYING_SLOT_LAYER:
+ case VARYING_SLOT_GS_VERTEX_FLAGS_IR3:
+ debug_assert(ctx->so->type == MESA_SHADER_GEOMETRY);
+ /* fall through */
case VARYING_SLOT_COL0:
case VARYING_SLOT_COL1:
case VARYING_SLOT_BFC0:
break;
if ((VARYING_SLOT_TEX0 <= slot) && (slot <= VARYING_SLOT_TEX7))
break;
- ir3_context_error(ctx, "unknown VS output name: %s\n",
+ ir3_context_error(ctx, "unknown %s shader output name: %s\n",
+ _mesa_shader_stage_to_string(ctx->so->type),
gl_varying_slot_name(slot));
}
} else {
}
static const unsigned max_sysvals[] = {
- [MESA_SHADER_FRAGMENT] = 24, // TODO
[MESA_SHADER_VERTEX] = 16,
+ [MESA_SHADER_GEOMETRY] = 16,
+ [MESA_SHADER_FRAGMENT] = 24, // TODO
[MESA_SHADER_COMPUTE] = 16, // TODO how many do we actually need?
[MESA_SHADER_KERNEL] = 16, // TODO how many do we actually need?
};
/* we need to leave room for sysvals:
*/
ninputs += max_sysvals[ctx->so->type];
+ if (ctx->so->type == MESA_SHADER_VERTEX)
+ noutputs += 8; /* gs or tess header + primitive_id */
ctx->ir = ir3_create(ctx->compiler, ctx->so->type, ninputs, noutputs);
ninputs -= max_sysvals[ctx->so->type];
+ if (ctx->so->key.has_gs) {
+ if (ctx->so->type == MESA_SHADER_VERTEX ||
+ ctx->so->type == MESA_SHADER_GEOMETRY) {
+ ctx->gs_header = create_input(ctx, 0);
+ ctx->primitive_id = create_input(ctx, 0);
+ }
+ }
+
/* for fragment shader, the vcoord input register is used as the
* base for bary.f varying fetch instrs:
*
0x3, vcoord);
}
+ if (ctx->primitive_id)
+ add_sysval_input(ctx, SYSTEM_VALUE_PRIMITIVE_ID, ctx->primitive_id);
+ if (ctx->gs_header)
+ add_sysval_input(ctx, SYSTEM_VALUE_GS_HEADER_IR3, ctx->gs_header);
+
/* Setup outputs: */
nir_foreach_variable(var, &ctx->s->outputs) {
setup_output(ctx, var);
}
+ /* Set up the gs header as an output for the vertex shader so it won't
+ * clobber it for the tess ctrl shader. */
+ if (ctx->so->type == MESA_SHADER_VERTEX) {
+ struct ir3_shader_variant *so = ctx->so;
+ if (ctx->primitive_id) {
+ unsigned n = so->outputs_count++;
+ so->outputs[n].slot = VARYING_SLOT_PRIMITIVE_ID;
+ so->outputs[n].regid = regid(n, 0);
+ ctx->ir->outputs[n * 4] = ctx->primitive_id;
+
+ compile_assert(ctx, n * 4 < ctx->ir->noutputs);
+ }
+
+ if (ctx->gs_header) {
+ unsigned n = so->outputs_count++;
+ so->outputs[n].slot = VARYING_SLOT_GS_HEADER_IR3;
+ so->outputs[n].regid = regid(n, 0);
+ ctx->ir->outputs[n * 4] = ctx->gs_header;
+
+ compile_assert(ctx, n * 4 < ctx->ir->noutputs);
+ }
+
+ }
+
/* Find # of samplers: */
nir_foreach_variable(var, &ctx->s->uniforms) {
ctx->so->num_samp += glsl_type_get_sampler_count(var->type);