#include "brw_context.h"
#include "brw_vs.h"
+/* Return the SrcReg index of the channels that can be immediate float operands
+ * instead of usage of PROGRAM_CONSTANT values through push/pull.
+ */
+static GLboolean
+brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg)
+{
+ int opcode_array[] = {
+ [OPCODE_ADD] = 2,
+ [OPCODE_CMP] = 3,
+ [OPCODE_DP3] = 2,
+ [OPCODE_DP4] = 2,
+ [OPCODE_DPH] = 2,
+ [OPCODE_MAX] = 1,
+ [OPCODE_MIN] = 2,
+ [OPCODE_MUL] = 2,
+ [OPCODE_SEQ] = 2,
+ [OPCODE_SGE] = 2,
+ [OPCODE_SGT] = 2,
+ [OPCODE_SLE] = 2,
+ [OPCODE_SLT] = 2,
+ [OPCODE_SNE] = 2,
+ [OPCODE_XPD] = 2,
+ };
+
+ /* These opcodes get broken down in a way that allow two
+ * args to be immediates.
+ */
+ if (opcode == OPCODE_MAD || opcode == OPCODE_LRP) {
+ if (arg == 1 || arg == 2)
+ return GL_TRUE;
+ }
+
+ if (opcode > ARRAY_SIZE(opcode_array))
+ return GL_FALSE;
+
+ return arg == opcode_array[opcode] - 1;
+}
static struct brw_reg get_tmp( struct brw_vs_compile *c )
{
if (intel->gen >= 6)
mrf = 6;
- else if (intel->is_ironlake)
+ else if (intel->gen == 5)
mrf = 8;
else
mrf = 4;
if (intel->gen >= 6)
c->prog_data.urb_entry_size = (attributes_in_vue + 4 + 7) / 8;
- else if (intel->is_ironlake)
+ else if (intel->gen == 5)
c->prog_data.urb_entry_size = (attributes_in_vue + 6 + 3) / 4;
else
c->prog_data.urb_entry_size = (attributes_in_vue + 2 + 3) / 4;
const GLint index = inst->SrcReg[argIndex].Index;
const GLboolean relAddr = inst->SrcReg[argIndex].RelAddr;
+ if (brw_vs_arg_can_be_immediate(inst->Opcode, argIndex)) {
+ const struct prog_src_register *src = &inst->SrcReg[argIndex];
+
+ if (src->Swizzle == MAKE_SWIZZLE4(SWIZZLE_ZERO,
+ SWIZZLE_ZERO,
+ SWIZZLE_ZERO,
+ SWIZZLE_ZERO)) {
+ return brw_imm_f(0.0f);
+ } else if (src->Swizzle == MAKE_SWIZZLE4(SWIZZLE_ONE,
+ SWIZZLE_ONE,
+ SWIZZLE_ONE,
+ SWIZZLE_ONE)) {
+ if (src->Negate)
+ return brw_imm_f(-1.0F);
+ else
+ return brw_imm_f(1.0F);
+ } else if (src->File == PROGRAM_CONSTANT) {
+ const struct gl_program_parameter_list *params;
+ float f;
+ int component = -1;
+
+ switch (src->Swizzle) {
+ case SWIZZLE_XXXX:
+ component = 0;
+ break;
+ case SWIZZLE_YYYY:
+ component = 1;
+ break;
+ case SWIZZLE_ZZZZ:
+ component = 2;
+ break;
+ case SWIZZLE_WWWW:
+ component = 3;
+ break;
+ }
+
+ if (component >= 0) {
+ params = c->vp->program.Base.Parameters;
+ f = params->ParameterValues[src->Index][component];
+
+ if (src->Abs)
+ f = fabs(f);
+ if (src->Negate)
+ f = -f;
+ return brw_imm_f(f);
+ }
+ }
+ }
+
switch (file) {
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
brw_MOV(p, offset(m0, 2), pos);
brw_MOV(p, offset(m0, 5), pos);
len_vertex_header = 4;
- } else if (intel->is_ironlake) {
+ } else if (intel->gen == 5) {
/* There are 20 DWs (D0-D19) in VUE header on Ironlake:
* dword 0-3 (m1) of the header is indices, point width, clip flags.
* dword 4-7 (m2) is the ndc position (set above)
}
}
-
-/**
- * Called after code generation to resolve subroutine calls and the
- * END instruction.
- * \param end_inst points to brw code for END instruction
- * \param last_inst points to last instruction emitted before vertex write
- */
-static void
-post_vs_emit( struct brw_vs_compile *c,
- struct brw_instruction *end_inst,
- struct brw_instruction *last_inst )
-{
- GLint offset;
-
- brw_resolve_cals(&c->func);
-
- /* patch up the END code to jump past subroutines, etc */
- offset = last_inst - end_inst;
- if (offset > 1) {
- brw_set_src1(end_inst, brw_imm_d(offset * 16));
- } else {
- end_inst->header.opcode = BRW_OPCODE_NOP;
- }
-}
-
static GLboolean
accumulator_contains(struct brw_vs_compile *c, struct brw_reg val)
{
struct intel_context *intel = &brw->intel;
const GLuint nr_insns = c->vp->program.Base.NumInstructions;
GLuint insn, if_depth = 0, loop_depth = 0;
- GLuint end_offset = 0;
- struct brw_instruction *end_inst, *last_inst;
struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH] = { 0 };
const struct brw_indirect stack_index = brw_indirect(0, 0);
GLuint index;
if_depth++;
break;
case OPCODE_ELSE:
+ assert(if_depth > 0);
if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]);
break;
case OPCODE_ENDIF:
loop_depth--;
- if (intel->is_ironlake)
+ if (intel->gen == 5)
br = 2;
inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
brw_MOV(p, brw_ip_reg(), deref_1d(stack_index, 0));
brw_set_access_mode(p, BRW_ALIGN_16);
break;
- case OPCODE_END:
- end_offset = p->nr_insn;
- /* this instruction will get patched later to jump past subroutine
- * code, etc.
- */
- brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ case OPCODE_END:
+ emit_vertex_write(c);
break;
case OPCODE_PRINT:
/* no-op */
release_tmps(c);
}
- end_inst = &p->store[end_offset];
- last_inst = &p->store[p->nr_insn];
-
- /* The END instruction will be patched to jump to this code */
- emit_vertex_write(c);
+ brw_resolve_cals(p);
- post_vs_emit(c, end_inst, last_inst);
+ brw_optimize(p);
if (INTEL_DEBUG & DEBUG_VS) {
int i;