mesa: initial support for ARB_geometry_shader4

laying down the foundation for everything and implementing most of the
stuff.
linking, gl_VerticesIn and multidimensional inputs are left.
This commit is contained in:
Zack Rusin
2010-06-28 17:31:21 -04:00
parent 0b50fcbd55
commit da7bd6a90e
63 changed files with 9351 additions and 7386 deletions

View File

@@ -459,6 +459,252 @@ st_translate_fragment_program(struct st_context *st,
}
}
void
st_translate_geometry_program(struct st_context *st,
struct st_geometry_program *stgp)
{
GLuint inputMapping[GEOM_ATTRIB_MAX];
GLuint outputMapping[GEOM_RESULT_MAX];
struct pipe_context *pipe = st->pipe;
enum pipe_error error;
GLuint attr;
const GLbitfield inputsRead = stgp->Base.Base.InputsRead;
GLuint vslot = 0;
GLuint num_generic = 0;
uint gs_num_inputs = 0;
uint gs_builtin_inputs = 0;
uint gs_array_offset = 0;
ubyte gs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
ubyte gs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
uint gs_num_outputs = 0;
GLint i;
GLuint maxSlot = 0;
struct ureg_program *ureg;
ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY );
if (ureg == NULL) {
return;
}
assert(0);
/* which vertex output goes to the first geometry input */
if (inputsRead & GEOM_BIT_VERTICES)
vslot = 0;
else
vslot = 1;
/*
* Convert Mesa program inputs to TGSI input register semantics.
*/
for (attr = 0; attr < GEOM_ATTRIB_MAX; attr++) {
if (inputsRead & (1 << attr)) {
const GLuint slot = gs_num_inputs;
gs_num_inputs++;
inputMapping[attr] = slot;
stgp->input_map[slot + gs_array_offset] = vslot - gs_builtin_inputs;
stgp->input_to_index[attr] = vslot;
stgp->index_to_input[vslot] = attr;
++vslot;
if (attr != GEOM_ATTRIB_VERTICES &&
attr != GEOM_ATTRIB_PRIMITIVE_ID) {
gs_array_offset += 2;
} else
++gs_builtin_inputs;
#if 1
debug_printf("input map at %d = %d\n",
slot + gs_array_offset, stgp->input_map[slot + gs_array_offset]);
#endif
switch (attr) {
case GEOM_ATTRIB_VERTICES:
debug_assert(0);
break;
case GEOM_ATTRIB_PRIMITIVE_ID:
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
stgp->input_semantic_index[slot] = 0;
break;
case GEOM_ATTRIB_POSITION:
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
stgp->input_semantic_index[slot] = 0;
break;
case GEOM_ATTRIB_COLOR0:
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
stgp->input_semantic_index[slot] = 0;
break;
case GEOM_ATTRIB_COLOR1:
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
stgp->input_semantic_index[slot] = 1;
break;
case GEOM_ATTRIB_FOG_FRAG_COORD:
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
stgp->input_semantic_index[slot] = 0;
break;
case GEOM_ATTRIB_TEX_COORD:
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
stgp->input_semantic_index[slot] = num_generic++;
break;
case GEOM_ATTRIB_VAR0:
/* fall-through */
default:
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
stgp->input_semantic_index[slot] = num_generic++;
}
}
}
/* initialize output semantics to defaults */
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
gs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
gs_output_semantic_index[i] = 0;
}
num_generic = 0;
/*
* Determine number of outputs, the (default) output register
* mapping and the semantic information for each output.
*/
for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
if (stgp->Base.Base.OutputsWritten & (1 << attr)) {
GLuint slot;
slot = gs_num_outputs;
gs_num_outputs++;
outputMapping[attr] = slot;
switch (attr) {
case GEOM_RESULT_POS:
assert(slot == 0);
gs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
gs_output_semantic_index[slot] = 0;
break;
case GEOM_RESULT_COL0:
gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
gs_output_semantic_index[slot] = 0;
break;
case GEOM_RESULT_COL1:
gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
gs_output_semantic_index[slot] = 1;
break;
case GEOM_RESULT_SCOL0:
gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
gs_output_semantic_index[slot] = 0;
break;
case GEOM_RESULT_SCOL1:
gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
gs_output_semantic_index[slot] = 1;
break;
case GEOM_RESULT_FOGC:
gs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
gs_output_semantic_index[slot] = 0;
break;
case GEOM_RESULT_PSIZ:
gs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
gs_output_semantic_index[slot] = 0;
break;
case GEOM_RESULT_TEX0:
case GEOM_RESULT_TEX1:
case GEOM_RESULT_TEX2:
case GEOM_RESULT_TEX3:
case GEOM_RESULT_TEX4:
case GEOM_RESULT_TEX5:
case GEOM_RESULT_TEX6:
case GEOM_RESULT_TEX7:
/* fall-through */
case GEOM_RESULT_VAR0:
/* fall-through */
default:
assert(slot < Elements(gs_output_semantic_name));
/* use default semantic info */
gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
gs_output_semantic_index[slot] = num_generic++;
}
}
}
assert(gs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
/* find max output slot referenced to compute gs_num_outputs */
for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
maxSlot = outputMapping[attr];
}
gs_num_outputs = maxSlot + 1;
#if 0 /* debug */
{
GLuint i;
printf("outputMapping? %d\n", outputMapping ? 1 : 0);
if (outputMapping) {
printf("attr -> slot\n");
for (i = 0; i < 16; i++) {
printf(" %2d %3d\n", i, outputMapping[i]);
}
}
printf("slot sem_name sem_index\n");
for (i = 0; i < gs_num_outputs; i++) {
printf(" %2d %d %d\n",
i,
gs_output_semantic_name[i],
gs_output_semantic_index[i]);
}
}
#endif
/* free old shader state, if any */
if (stgp->tgsi.tokens) {
st_free_tokens(stgp->tgsi.tokens);
stgp->tgsi.tokens = NULL;
}
if (stgp->driver_shader) {
cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
stgp->driver_shader = NULL;
}
ureg_property_gs_input_prim(ureg, stgp->Base.InputType);
ureg_property_gs_output_prim(ureg, stgp->Base.OutputType);
ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut);
error = st_translate_mesa_program(st->ctx,
TGSI_PROCESSOR_GEOMETRY,
ureg,
&stgp->Base.Base,
/* inputs */
gs_num_inputs,
inputMapping,
stgp->input_semantic_name,
stgp->input_semantic_index,
NULL,
/* outputs */
gs_num_outputs,
outputMapping,
gs_output_semantic_name,
gs_output_semantic_index,
FALSE);
stgp->num_inputs = gs_num_inputs;
stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
ureg_destroy( ureg );
stgp->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
_mesa_print_program(&stgp->Base.Base);
debug_printf("\n");
}
if (ST_DEBUG & DEBUG_TGSI) {
tgsi_dump(stgp->tgsi.tokens, 0);
debug_printf("\n");
}
}
/**
* Debug- print current shader text