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:
@@ -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
|
||||
|
Reference in New Issue
Block a user