|
|
@@ -932,61 +932,52 @@ st_get_fp_variant(struct st_context *st, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Translate a geometry program to create a new variant. |
|
|
|
* Translate a program. This is common code for geometry and tessellation |
|
|
|
* shaders. |
|
|
|
*/ |
|
|
|
static struct st_gp_variant * |
|
|
|
st_translate_geometry_program(struct st_context *st, |
|
|
|
struct st_geometry_program *stgp, |
|
|
|
const struct st_gp_variant_key *key) |
|
|
|
static void |
|
|
|
st_translate_program_common(struct st_context *st, |
|
|
|
struct gl_program *prog, |
|
|
|
struct glsl_to_tgsi_visitor *glsl_to_tgsi, |
|
|
|
struct ureg_program *ureg, |
|
|
|
unsigned tgsi_processor, |
|
|
|
struct pipe_shader_state *out_state) |
|
|
|
{ |
|
|
|
GLuint inputSlotToAttr[VARYING_SLOT_MAX]; |
|
|
|
GLuint inputMapping[VARYING_SLOT_MAX]; |
|
|
|
GLuint outputSlotToAttr[VARYING_SLOT_MAX]; |
|
|
|
GLuint outputMapping[VARYING_SLOT_MAX]; |
|
|
|
struct pipe_context *pipe = st->pipe; |
|
|
|
GLuint inputSlotToAttr[VARYING_SLOT_TESS_MAX]; |
|
|
|
GLuint inputMapping[VARYING_SLOT_TESS_MAX]; |
|
|
|
GLuint outputSlotToAttr[VARYING_SLOT_TESS_MAX]; |
|
|
|
GLuint outputMapping[VARYING_SLOT_TESS_MAX]; |
|
|
|
GLuint attr; |
|
|
|
|
|
|
|
uint gs_num_inputs = 0; |
|
|
|
|
|
|
|
ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; |
|
|
|
ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; |
|
|
|
uint num_inputs = 0; |
|
|
|
|
|
|
|
ubyte gs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; |
|
|
|
ubyte gs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; |
|
|
|
uint gs_num_outputs = 0; |
|
|
|
ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; |
|
|
|
ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; |
|
|
|
uint num_outputs = 0; |
|
|
|
|
|
|
|
GLint i; |
|
|
|
struct ureg_program *ureg; |
|
|
|
struct pipe_shader_state state = {0}; |
|
|
|
struct st_gp_variant *gpv; |
|
|
|
|
|
|
|
gpv = CALLOC_STRUCT(st_gp_variant); |
|
|
|
if (!gpv) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
ureg = ureg_create_with_screen(TGSI_PROCESSOR_GEOMETRY, st->pipe->screen); |
|
|
|
if (ureg == NULL) { |
|
|
|
free(gpv); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
memset(inputSlotToAttr, 0, sizeof(inputSlotToAttr)); |
|
|
|
memset(inputMapping, 0, sizeof(inputMapping)); |
|
|
|
memset(outputSlotToAttr, 0, sizeof(outputSlotToAttr)); |
|
|
|
memset(outputMapping, 0, sizeof(outputMapping)); |
|
|
|
memset(out_state, 0, sizeof(*out_state)); |
|
|
|
|
|
|
|
/* |
|
|
|
* Convert Mesa program inputs to TGSI input register semantics. |
|
|
|
*/ |
|
|
|
for (attr = 0; attr < VARYING_SLOT_MAX; attr++) { |
|
|
|
if ((stgp->Base.Base.InputsRead & BITFIELD64_BIT(attr)) != 0) { |
|
|
|
const GLuint slot = gs_num_inputs++; |
|
|
|
if ((prog->InputsRead & BITFIELD64_BIT(attr)) != 0) { |
|
|
|
const GLuint slot = num_inputs++; |
|
|
|
|
|
|
|
inputMapping[attr] = slot; |
|
|
|
inputSlotToAttr[slot] = attr; |
|
|
|
|
|
|
|
switch (attr) { |
|
|
|
case VARYING_SLOT_PRIMITIVE_ID: |
|
|
|
assert(tgsi_processor == TGSI_PROCESSOR_GEOMETRY); |
|
|
|
input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID; |
|
|
|
input_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
@@ -1038,19 +1029,33 @@ st_translate_geometry_program(struct st_context *st, |
|
|
|
/* fall through */ |
|
|
|
case VARYING_SLOT_VAR0: |
|
|
|
default: |
|
|
|
assert(attr >= VARYING_SLOT_VAR0 && attr < VARYING_SLOT_MAX); |
|
|
|
assert(attr >= VARYING_SLOT_VAR0 || |
|
|
|
(attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7)); |
|
|
|
input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; |
|
|
|
input_semantic_index[slot] = |
|
|
|
st_get_generic_varying_index(st, attr); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Also add patch inputs. */ |
|
|
|
for (attr = 0; attr < 32; attr++) { |
|
|
|
if (prog->PatchInputsRead & (1 << attr)) { |
|
|
|
GLuint slot = num_inputs++; |
|
|
|
GLuint patch_attr = VARYING_SLOT_PATCH0 + attr; |
|
|
|
|
|
|
|
inputMapping[patch_attr] = slot; |
|
|
|
inputSlotToAttr[slot] = patch_attr; |
|
|
|
input_semantic_name[slot] = TGSI_SEMANTIC_PATCH; |
|
|
|
input_semantic_index[slot] = attr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* 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; |
|
|
|
output_semantic_name[i] = TGSI_SEMANTIC_GENERIC; |
|
|
|
output_semantic_index[i] = 0; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
@@ -1058,8 +1063,8 @@ st_translate_geometry_program(struct st_context *st, |
|
|
|
* mapping and the semantic information for each output. |
|
|
|
*/ |
|
|
|
for (attr = 0; attr < VARYING_SLOT_MAX; attr++) { |
|
|
|
if (stgp->Base.Base.OutputsWritten & BITFIELD64_BIT(attr)) { |
|
|
|
GLuint slot = gs_num_outputs++; |
|
|
|
if (prog->OutputsWritten & BITFIELD64_BIT(attr)) { |
|
|
|
GLuint slot = num_outputs++; |
|
|
|
|
|
|
|
outputMapping[attr] = slot; |
|
|
|
outputSlotToAttr[slot] = attr; |
|
|
@@ -1067,56 +1072,64 @@ st_translate_geometry_program(struct st_context *st, |
|
|
|
switch (attr) { |
|
|
|
case VARYING_SLOT_POS: |
|
|
|
assert(slot == 0); |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_POSITION; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_COL0: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_COL1: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; |
|
|
|
gs_output_semantic_index[slot] = 1; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_COLOR; |
|
|
|
output_semantic_index[slot] = 1; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_BFC0: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_BFC1: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; |
|
|
|
gs_output_semantic_index[slot] = 1; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR; |
|
|
|
output_semantic_index[slot] = 1; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_FOGC: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_FOG; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_PSIZ: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_CLIP_VERTEX: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_CLIP_DIST0: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_CLIP_DIST1: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; |
|
|
|
gs_output_semantic_index[slot] = 1; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; |
|
|
|
output_semantic_index[slot] = 1; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_LAYER: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_LAYER; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_LAYER; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_PRIMITIVE_ID: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_PRIMID; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_PRIMID; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_VIEWPORT: |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_VIEWPORT_INDEX; |
|
|
|
gs_output_semantic_index[slot] = 0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_VIEWPORT_INDEX; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_TESS_LEVEL_OUTER: |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_TESSOUTER; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_TESS_LEVEL_INNER: |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_TESSINNER; |
|
|
|
output_semantic_index[slot] = 0; |
|
|
|
break; |
|
|
|
case VARYING_SLOT_TEX0: |
|
|
|
case VARYING_SLOT_TEX1: |
|
|
@@ -1127,36 +1140,44 @@ st_translate_geometry_program(struct st_context *st, |
|
|
|
case VARYING_SLOT_TEX6: |
|
|
|
case VARYING_SLOT_TEX7: |
|
|
|
if (st->needs_texcoord_semantic) { |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD; |
|
|
|
gs_output_semantic_index[slot] = attr - VARYING_SLOT_TEX0; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD; |
|
|
|
output_semantic_index[slot] = attr - VARYING_SLOT_TEX0; |
|
|
|
break; |
|
|
|
} |
|
|
|
/* fall through */ |
|
|
|
case VARYING_SLOT_VAR0: |
|
|
|
default: |
|
|
|
assert(slot < ARRAY_SIZE(gs_output_semantic_name)); |
|
|
|
assert(attr >= VARYING_SLOT_VAR0); |
|
|
|
gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; |
|
|
|
gs_output_semantic_index[slot] = |
|
|
|
assert(slot < ARRAY_SIZE(output_semantic_name)); |
|
|
|
assert(attr >= VARYING_SLOT_VAR0 || |
|
|
|
(attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7)); |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; |
|
|
|
output_semantic_index[slot] = |
|
|
|
st_get_generic_varying_index(st, attr); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, stgp->Base.InputType); |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, stgp->Base.OutputType); |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, |
|
|
|
stgp->Base.VerticesOut); |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, stgp->Base.Invocations); |
|
|
|
/* Also add patch outputs. */ |
|
|
|
for (attr = 0; attr < 32; attr++) { |
|
|
|
if (prog->PatchOutputsWritten & (1 << attr)) { |
|
|
|
GLuint slot = num_outputs++; |
|
|
|
GLuint patch_attr = VARYING_SLOT_PATCH0 + attr; |
|
|
|
|
|
|
|
outputMapping[patch_attr] = slot; |
|
|
|
outputSlotToAttr[slot] = patch_attr; |
|
|
|
output_semantic_name[slot] = TGSI_SEMANTIC_PATCH; |
|
|
|
output_semantic_index[slot] = attr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
st_translate_program(st->ctx, |
|
|
|
TGSI_PROCESSOR_GEOMETRY, |
|
|
|
tgsi_processor, |
|
|
|
ureg, |
|
|
|
stgp->glsl_to_tgsi, |
|
|
|
&stgp->Base.Base, |
|
|
|
glsl_to_tgsi, |
|
|
|
prog, |
|
|
|
/* inputs */ |
|
|
|
gs_num_inputs, |
|
|
|
num_inputs, |
|
|
|
inputMapping, |
|
|
|
inputSlotToAttr, |
|
|
|
input_semantic_name, |
|
|
@@ -1164,30 +1185,64 @@ st_translate_geometry_program(struct st_context *st, |
|
|
|
NULL, |
|
|
|
NULL, |
|
|
|
/* outputs */ |
|
|
|
gs_num_outputs, |
|
|
|
num_outputs, |
|
|
|
outputMapping, |
|
|
|
outputSlotToAttr, |
|
|
|
gs_output_semantic_name, |
|
|
|
gs_output_semantic_index, |
|
|
|
output_semantic_name, |
|
|
|
output_semantic_index, |
|
|
|
FALSE, |
|
|
|
FALSE); |
|
|
|
|
|
|
|
state.tokens = ureg_get_tokens(ureg, NULL); |
|
|
|
out_state->tokens = ureg_get_tokens(ureg, NULL); |
|
|
|
ureg_destroy(ureg); |
|
|
|
|
|
|
|
st_translate_stream_output_info(stgp->glsl_to_tgsi, |
|
|
|
st_translate_stream_output_info(glsl_to_tgsi, |
|
|
|
outputMapping, |
|
|
|
&state.stream_output); |
|
|
|
&out_state->stream_output); |
|
|
|
|
|
|
|
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) { |
|
|
|
_mesa_print_program(&stgp->Base.Base); |
|
|
|
_mesa_print_program(prog); |
|
|
|
debug_printf("\n"); |
|
|
|
} |
|
|
|
|
|
|
|
if (ST_DEBUG & DEBUG_TGSI) { |
|
|
|
tgsi_dump(state.tokens, 0); |
|
|
|
tgsi_dump(out_state->tokens, 0); |
|
|
|
debug_printf("\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Translate a geometry program to create a new variant. |
|
|
|
*/ |
|
|
|
static struct st_gp_variant * |
|
|
|
st_translate_geometry_program(struct st_context *st, |
|
|
|
struct st_geometry_program *stgp, |
|
|
|
const struct st_gp_variant_key *key) |
|
|
|
{ |
|
|
|
struct pipe_context *pipe = st->pipe; |
|
|
|
struct ureg_program *ureg; |
|
|
|
struct st_gp_variant *gpv; |
|
|
|
struct pipe_shader_state state; |
|
|
|
|
|
|
|
ureg = ureg_create_with_screen(TGSI_PROCESSOR_GEOMETRY, st->pipe->screen); |
|
|
|
if (ureg == NULL) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, stgp->Base.InputType); |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, stgp->Base.OutputType); |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, |
|
|
|
stgp->Base.VerticesOut); |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, stgp->Base.Invocations); |
|
|
|
|
|
|
|
st_translate_program_common(st, &stgp->Base.Base, stgp->glsl_to_tgsi, ureg, |
|
|
|
TGSI_PROCESSOR_GEOMETRY, &state); |
|
|
|
|
|
|
|
gpv = CALLOC_STRUCT(st_gp_variant); |
|
|
|
if (!gpv) { |
|
|
|
ureg_free_tokens(state.tokens); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* fill in new variant */ |
|
|
|
gpv->driver_shader = pipe->create_gs_state(pipe, &state); |
|
|
@@ -1237,7 +1292,34 @@ st_translate_tessctrl_program(struct st_context *st, |
|
|
|
struct st_tessctrl_program *sttcp, |
|
|
|
const struct st_tcp_variant_key *key) |
|
|
|
{ |
|
|
|
return NULL; /* will be updated in the next commit */ |
|
|
|
struct pipe_context *pipe = st->pipe; |
|
|
|
struct ureg_program *ureg; |
|
|
|
struct st_tcp_variant *tcpv; |
|
|
|
struct pipe_shader_state state; |
|
|
|
|
|
|
|
ureg = ureg_create_with_screen(TGSI_PROCESSOR_TESS_CTRL, pipe->screen); |
|
|
|
if (ureg == NULL) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT, |
|
|
|
sttcp->Base.VerticesOut); |
|
|
|
|
|
|
|
st_translate_program_common(st, &sttcp->Base.Base, sttcp->glsl_to_tgsi, |
|
|
|
ureg, TGSI_PROCESSOR_TESS_CTRL, &state); |
|
|
|
|
|
|
|
tcpv = CALLOC_STRUCT(st_tcp_variant); |
|
|
|
if (!tcpv) { |
|
|
|
ureg_free_tokens(state.tokens); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* fill in new variant */ |
|
|
|
tcpv->driver_shader = pipe->create_tcs_state(pipe, &state); |
|
|
|
tcpv->key = *key; |
|
|
|
|
|
|
|
ureg_free_tokens(state.tokens); |
|
|
|
return tcpv; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@@ -1280,7 +1362,56 @@ st_translate_tesseval_program(struct st_context *st, |
|
|
|
struct st_tesseval_program *sttep, |
|
|
|
const struct st_tep_variant_key *key) |
|
|
|
{ |
|
|
|
return NULL; /* will be updated in the next commit */ |
|
|
|
struct pipe_context *pipe = st->pipe; |
|
|
|
struct ureg_program *ureg; |
|
|
|
struct st_tep_variant *tepv; |
|
|
|
struct pipe_shader_state state; |
|
|
|
|
|
|
|
ureg = ureg_create_with_screen(TGSI_PROCESSOR_TESS_EVAL, pipe->screen); |
|
|
|
if (ureg == NULL) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
if (sttep->Base.PrimitiveMode == GL_ISOLINES) |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, GL_LINES); |
|
|
|
else |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, sttep->Base.PrimitiveMode); |
|
|
|
|
|
|
|
switch (sttep->Base.Spacing) { |
|
|
|
case GL_EQUAL: |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_TES_SPACING, PIPE_TESS_SPACING_EQUAL); |
|
|
|
break; |
|
|
|
case GL_FRACTIONAL_EVEN: |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_TES_SPACING, |
|
|
|
PIPE_TESS_SPACING_FRACTIONAL_EVEN); |
|
|
|
break; |
|
|
|
case GL_FRACTIONAL_ODD: |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_TES_SPACING, |
|
|
|
PIPE_TESS_SPACING_FRACTIONAL_ODD); |
|
|
|
break; |
|
|
|
default: |
|
|
|
assert(0); |
|
|
|
} |
|
|
|
|
|
|
|
ureg_property(ureg, TGSI_PROPERTY_TES_VERTEX_ORDER_CW, |
|
|
|
sttep->Base.VertexOrder == GL_CW); |
|
|
|
ureg_property(ureg, TGSI_PROPERTY_TES_POINT_MODE, sttep->Base.PointMode); |
|
|
|
|
|
|
|
st_translate_program_common(st, &sttep->Base.Base, sttep->glsl_to_tgsi, |
|
|
|
ureg, TGSI_PROCESSOR_TESS_EVAL, &state); |
|
|
|
|
|
|
|
tepv = CALLOC_STRUCT(st_tep_variant); |
|
|
|
if (!tepv) { |
|
|
|
ureg_free_tokens(state.tokens); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* fill in new variant */ |
|
|
|
tepv->driver_shader = pipe->create_tes_state(pipe, &state); |
|
|
|
tepv->key = *key; |
|
|
|
|
|
|
|
ureg_free_tokens(state.tokens); |
|
|
|
return tepv; |
|
|
|
} |
|
|
|
|
|
|
|
|