*/
#include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/p_state.h"
-#include "pipe/p_context.h"
#include "tgsi/tgsi_ureg.h"
#include "st_mesa_to_tgsi.h"
#include "st_context.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+
+#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \
+ (1 << PROGRAM_ENV_PARAM) | \
+ (1 << PROGRAM_STATE_VAR) | \
+ (1 << PROGRAM_NAMED_PARAM) | \
+ (1 << PROGRAM_CONSTANT) | \
+ (1 << PROGRAM_UNIFORM))
+
+
struct label {
unsigned branch_target;
unsigned token;
else if (t->procType == TGSI_PROCESSOR_FRAGMENT)
assert(index < FRAG_RESULT_MAX);
else
- assert(0 && "geom shaders not handled in dst_register() yet");
+ assert(index < GEOM_RESULT_MAX);
assert(t->outputMapping[index] < Elements(t->outputs));
return ureg_src_undef();
case PROGRAM_TEMPORARY:
- ASSERT(index >= 0);
+ assert(index >= 0);
if (ureg_dst_is_undef(t->temps[index]))
t->temps[index] = ureg_DECL_temporary( t->ureg );
assert(index < Elements(t->temps));
case PROGRAM_ENV_PARAM:
case PROGRAM_LOCAL_PARAM:
case PROGRAM_UNIFORM:
- ASSERT(index >= 0);
+ assert(index >= 0);
return t->constants[index];
case PROGRAM_STATE_VAR:
case PROGRAM_CONSTANT: /* ie, immediate */
{
struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index );
+ if (t->procType == TGSI_PROCESSOR_GEOMETRY && SrcReg->HasIndex2) {
+ src = src_register( t, SrcReg->File, SrcReg->Index2 );
+ if (SrcReg->RelAddr2)
+ src = ureg_src_dimension_indirect( src, ureg_src(t->address[0]),
+ SrcReg->Index);
+ else
+ src = ureg_src_dimension( src, SrcReg->Index);
+ }
+
src = ureg_swizzle( src,
GET_SWZ( SrcReg->Swizzle, 0 ) & 0x3,
GET_SWZ( SrcReg->Swizzle, 1 ) & 0x3,
return TGSI_OPCODE_DST;
case OPCODE_ELSE:
return TGSI_OPCODE_ELSE;
+ case OPCODE_EMIT_VERTEX:
+ return TGSI_OPCODE_EMIT;
+ case OPCODE_END_PRIMITIVE:
+ return TGSI_OPCODE_ENDPRIM;
case OPCODE_ENDIF:
return TGSI_OPCODE_ENDIF;
case OPCODE_ENDLOOP:
struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg);
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
- ureg_ADD(ureg,
- ureg_writemask(wpos_temp, TGSI_WRITEMASK_X | TGSI_WRITEMASK_Y),
- wpos_input, ureg_imm1f(ureg, value));
+ /* Note that we bias X and Y and pass Z and W through unchanged.
+ * The shader might also use gl_FragCoord.w and .z.
+ */
+ ureg_ADD(ureg, wpos_temp, wpos_input,
+ ureg_imm4f(ureg, value, value, 0.0f, 0.0f));
t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
}
unsigned i;
enum pipe_error ret = PIPE_OK;
+ assert(numInputs <= Elements(t->inputs));
+ assert(numOutputs <= Elements(t->outputs));
+
t = &translate;
memset(t, 0, sizeof *t);
}
}
}
+ else if (procType == TGSI_PROCESSOR_GEOMETRY) {
+ for (i = 0; i < numInputs; i++) {
+ t->inputs[i] = ureg_DECL_gs_input(ureg,
+ i,
+ inputSemanticName[i],
+ inputSemanticIndex[i]);
+ }
+
+ for (i = 0; i < numOutputs; i++) {
+ t->outputs[i] = ureg_DECL_output( ureg,
+ outputSemanticName[i],
+ outputSemanticIndex[i] );
+ }
+ }
else {
+ assert(procType == TGSI_PROCESSOR_VERTEX);
+
for (i = 0; i < numInputs; i++) {
t->inputs[i] = ureg_DECL_vs_input(ureg, i);
}
t->address[0] = ureg_DECL_address( ureg );
}
+ if (program->IndirectRegisterFiles & (1 << PROGRAM_TEMPORARY)) {
+ /* If temps are accessed with indirect addressing, declare temporaries
+ * in sequential order. Else, we declare them on demand elsewhere.
+ */
+ for (i = 0; i < program->NumTemporaries; i++) {
+ /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */
+ t->temps[i] = ureg_DECL_temporary( t->ureg );
+ }
+ }
+
/* Emit constants and immediates. Mesa uses a single index space
* for these, so we put all the translated regs in t->constants.
*/
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto out;
}
-
+
for (i = 0; i < program->Parameters->NumParameters; i++) {
switch (program->Parameters->Parameters[i].Type) {
case PROGRAM_ENV_PARAM:
t->constants[i] = ureg_DECL_constant( ureg, i );
break;
- /* Emit immediates only when there is no address register
- * in use. FIXME: Be smarter and recognize param arrays:
+ /* Emit immediates only when there's no indirect addressing of
+ * the const buffer.
+ * FIXME: Be smarter and recognize param arrays:
* indirect addressing is only valid within the referenced
* array.
*/
case PROGRAM_CONSTANT:
- if (program->NumAddressRegs > 0)
+ if (program->IndirectRegisterFiles & PROGRAM_ANY_CONST)
t->constants[i] = ureg_DECL_constant( ureg, i );
else
t->constants[i] =