#include "shader/program.h"
#include "shader/prog_instruction.h"
#include "shader/prog_parameter.h"
#include "shader/program.h"
#include "shader/prog_instruction.h"
#include "shader/prog_parameter.h"
emitInfo->Subroutines = (struct gl_program **)
_mesa_realloc(emitInfo->Subroutines,
emitInfo->Subroutines = (struct gl_program **)
_mesa_realloc(emitInfo->Subroutines,
- n * sizeof(struct gl_program),
- (n + 1) * sizeof(struct gl_program));
+ n * sizeof(struct gl_program *),
+ (n + 1) * sizeof(struct gl_program *));
emitInfo->Subroutines[n] = ctx->Driver.NewProgram(ctx, emitInfo->prog->Target, 0);
emitInfo->Subroutines[n]->Parameters = emitInfo->prog->Parameters;
emitInfo->NumSubroutines++;
emitInfo->Subroutines[n] = ctx->Driver.NewProgram(ctx, emitInfo->prog->Target, 0);
emitInfo->Subroutines[n]->Parameters = emitInfo->prog->Parameters;
emitInfo->NumSubroutines++;
_mesa_realloc_instructions(prog->Instructions,
prog->NumInstructions,
emitInfo->MaxInstructions);
_mesa_realloc_instructions(prog->Instructions,
prog->NumInstructions,
emitInfo->MaxInstructions);
static struct prog_instruction *
emit_arl_load(slang_emit_info *emitInfo,
static struct prog_instruction *
emit_arl_load(slang_emit_info *emitInfo,
- inst->SrcReg[0].File = file;
- inst->SrcReg[0].Index = index;
- inst->SrcReg[0].Swizzle = fix_swizzle(swizzle);
- inst->DstReg.File = PROGRAM_ADDRESS;
- inst->DstReg.Index = 0;
- inst->DstReg.WriteMask = WRITEMASK_X;
+ if (inst) {
+ inst->SrcReg[0].File = file;
+ inst->SrcReg[0].Index = index;
+ inst->SrcReg[0].Swizzle = fix_swizzle(swizzle);
+ inst->DstReg.File = PROGRAM_ADDRESS;
+ inst->DstReg.Index = 0;
+ inst->DstReg.WriteMask = WRITEMASK_X;
+ }
emit_comment(slang_emit_info *emitInfo, const char *comment)
{
struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP);
emit_comment(slang_emit_info *emitInfo, const char *comment)
{
struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP);
emit(emitInfo, n->Children[0]->Children[0]); /* A */
emit(emitInfo, n->Children[0]->Children[1]); /* B */
emit(emitInfo, n->Children[1]); /* C */
emit(emitInfo, n->Children[0]->Children[0]); /* A */
emit(emitInfo, n->Children[0]->Children[1]); /* B */
emit(emitInfo, n->Children[1]); /* C */
emit(emitInfo, n->Children[0]); /* A */
emit(emitInfo, n->Children[1]->Children[0]); /* B */
emit(emitInfo, n->Children[1]->Children[1]); /* C */
emit(emitInfo, n->Children[0]); /* A */
emit(emitInfo, n->Children[1]->Children[0]); /* B */
emit(emitInfo, n->Children[1]->Children[1]); /* C */
emit(emitInfo, n->Children[1]);
if (n->Children[0]->Store->Size != n->Children[1]->Store->Size) {
emit(emitInfo, n->Children[1]);
if (n->Children[0]->Store->Size != n->Children[1]->Store->Size) {
inst_comment(inst, "Compare values");
/* Compute val = DOT(temp, temp) (reduction) */
inst_comment(inst, "Compare values");
/* Compute val = DOT(temp, temp) (reduction) */
inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/
inst_comment(inst, "Reduce vec to bool");
inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/
inst_comment(inst, "Reduce vec to bool");
/* ADD accTemp, accTemp, sneTemp; # like logical-OR */
inst = emit_instruction(emitInfo, OPCODE_ADD,
&accTemp, /* dest */
&accTemp,
&sneTemp,
NULL);
/* ADD accTemp, accTemp, sneTemp; # like logical-OR */
inst = emit_instruction(emitInfo, OPCODE_ADD,
&accTemp, /* dest */
&accTemp,
&sneTemp,
NULL);
inst_comment(inst, "End struct/array comparison");
if (n->Opcode == IR_EQUAL) {
inst_comment(inst, "End struct/array comparison");
if (n->Opcode == IR_EQUAL) {
* the intermediate result. Use a temp register instead.
*/
_mesa_bzero(&tmpNode, sizeof(tmpNode));
* the intermediate result. Use a temp register instead.
*/
_mesa_bzero(&tmpNode, sizeof(tmpNode));
/* tmp = max(ch[0], ch[1]) */
inst = emit_instruction(emitInfo, OPCODE_MAX,
/* tmp = max(ch[0], ch[1]) */
inst = emit_instruction(emitInfo, OPCODE_MAX,
/* n->dest = min(tmp, ch[2]) */
inst = emit_instruction(emitInfo, OPCODE_MIN,
/* n->dest = min(tmp, ch[2]) */
inst = emit_instruction(emitInfo, OPCODE_MIN,
* really just a NOP to attach the label to.
*/
inst = new_instruction(emitInfo, OPCODE_BGNSUB);
* really just a NOP to attach the label to.
*/
inst = new_instruction(emitInfo, OPCODE_BGNSUB);
inst = prev_instruction(emitInfo);
if (inst && inst->Opcode != OPCODE_RET) {
inst = new_instruction(emitInfo, OPCODE_RET);
inst = prev_instruction(emitInfo);
if (inst && inst->Opcode != OPCODE_RET) {
inst = new_instruction(emitInfo, OPCODE_RET);
}
if (emitInfo->EmitBeginEndSub) {
inst = new_instruction(emitInfo, OPCODE_ENDSUB);
}
if (emitInfo->EmitBeginEndSub) {
inst = new_instruction(emitInfo, OPCODE_ENDSUB);
/* emit the function call */
inst = new_instruction(emitInfo, OPCODE_CAL);
/* emit the function call */
inst = new_instruction(emitInfo, OPCODE_CAL);
/* The branch target is just the subroutine number (changed later) */
inst->BranchTarget = subroutineId;
inst_comment(inst, n->Label->Name);
/* The branch target is just the subroutine number (changed later) */
inst->BranchTarget = subroutineId;
inst_comment(inst, n->Label->Name);
assert(n->Opcode == IR_RETURN);
assert(n->Label);
inst = new_instruction(emitInfo, OPCODE_RET);
assert(n->Opcode == IR_RETURN);
assert(n->Label);
inst = new_instruction(emitInfo, OPCODE_RET);
* Note that ARB-KILL depends on sign of vector operand.
*/
inst = new_instruction(emitInfo, OPCODE_KIL_NV);
* Note that ARB-KILL depends on sign of vector operand.
*/
inst = new_instruction(emitInfo, OPCODE_KIL_NV);
inst->DstReg.CondMask = COND_TR; /* always kill */
assert(emitInfo->prog->Target == GL_FRAGMENT_PROGRAM_ARB);
inst->DstReg.CondMask = COND_TR; /* always kill */
assert(emitInfo->prog->Target == GL_FRAGMENT_PROGRAM_ARB);
inst = emit(emitInfo, n->Children[1]);
if (!n->Children[1]->Store || n->Children[1]->Store->Index < 0) {
inst = emit(emitInfo, n->Children[1]);
if (!n->Children[1]->Store || n->Children[1]->Store->Index < 0) {
dstAnnot = storage_annotation(n->Children[0], emitInfo->prog);
srcAnnot = storage_annotation(n->Children[1], emitInfo->prog);
inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
dstAnnot = storage_annotation(n->Children[0], emitInfo->prog);
srcAnnot = storage_annotation(n->Children[1], emitInfo->prog);
inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
inst->CondUpdate = GL_TRUE;
inst_comment(inst, "COND expr");
_slang_free_temp(emitInfo->vt, n->Store);
inst->CondUpdate = GL_TRUE;
inst_comment(inst, "COND expr");
_slang_free_temp(emitInfo->vt, n->Store);
inst_comment(inst, "NOT");
free_node_storage(emitInfo->vt, n->Children[0]);
inst_comment(inst, "NOT");
free_node_storage(emitInfo->vt, n->Children[0]);
if (emitInfo->EmitHighLevelInstructions) {
if (emitInfo->EmitCondCodes) {
/* IF condcode THEN ... */
if (emitInfo->EmitHighLevelInstructions) {
if (emitInfo->EmitCondCodes) {
/* IF condcode THEN ... */
ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */
/* only test the cond code (1 of 4) that was updated by the
* previous instruction.
ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */
/* only test the cond code (1 of 4) that was updated by the
* previous instruction.
- emit_instruction(emitInfo, OPCODE_IF,
- NULL, /* dst */
- n->Children[0]->Store, /* op0 */
- NULL,
- NULL);
+ inst = emit_instruction(emitInfo, OPCODE_IF,
+ NULL, /* dst */
+ n->Children[0]->Store, /* op0 */
+ NULL,
+ NULL);
+ if (!inst) {
+ return NULL;
+ }
}
}
else {
/* conditional jump to else, or endif */
struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_BRA);
}
}
else {
/* conditional jump to else, or endif */
struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_BRA);
ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */
inst_comment(ifInst, "if zero");
ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */
inst_comment(ifInst, "if zero");
ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
inst_comment(inst, "else");
inst->DstReg.CondMask = COND_TR; /* always branch */
inst_comment(inst, "else");
inst->DstReg.CondMask = COND_TR; /* always branch */
- if (n->Children[2]) {
- prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions;
+ if (elseInstLoc) {
+ /* point ELSE instruction BranchTarget at ENDIF */
+ if (emitInfo->EmitHighLevelInstructions) {
+ prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions - 1;
+ }
+ else {
+ prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions;
+ }
/* emit OPCODE_BGNLOOP */
beginInstLoc = prog->NumInstructions;
if (emitInfo->EmitHighLevelInstructions) {
/* emit OPCODE_BGNLOOP */
beginInstLoc = prog->NumInstructions;
if (emitInfo->EmitHighLevelInstructions) {
if (emitInfo->EmitHighLevelInstructions) {
/* emit OPCODE_ENDLOOP */
endInst = new_instruction(emitInfo, OPCODE_ENDLOOP);
if (emitInfo->EmitHighLevelInstructions) {
/* emit OPCODE_ENDLOOP */
endInst = new_instruction(emitInfo, OPCODE_ENDLOOP);
}
else {
/* emit unconditional BRA-nch */
endInst = new_instruction(emitInfo, OPCODE_BRA);
}
else {
/* emit unconditional BRA-nch */
endInst = new_instruction(emitInfo, OPCODE_BRA);
endInst->DstReg.CondMask = COND_TR; /* always true */
}
/* ENDLOOP's BranchTarget points to the BGNLOOP inst */
endInst->DstReg.CondMask = COND_TR; /* always true */
}
/* ENDLOOP's BranchTarget points to the BGNLOOP inst */
/* Done emitting loop code. Now walk over the loop's linked list of
* BREAK and CONT nodes, filling in their BranchTarget fields (which
/* Done emitting loop code. Now walk over the loop's linked list of
* BREAK and CONT nodes, filling in their BranchTarget fields (which
*/
for (ir = n->List; ir; ir = ir->List) {
struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
*/
for (ir = n->List; ir; ir = ir->List) {
struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
ir->Opcode == IR_BREAK_IF_TRUE) {
assert(inst->Opcode == OPCODE_BRK ||
inst->Opcode == OPCODE_BRA);
ir->Opcode == IR_BREAK_IF_TRUE) {
assert(inst->Opcode == OPCODE_BRK ||
inst->Opcode == OPCODE_BRA);
- /* go to instruction after end of loop */
- inst->BranchTarget = endInstLoc + 1;
+ /* go to instruction at end of loop */
+ if (emitInfo->EmitHighLevelInstructions) {
+ inst->BranchTarget = endInstLoc;
+ }
+ else {
+ inst->BranchTarget = endInstLoc + 1;
+ }
}
n->InstLocation = emitInfo->prog->NumInstructions;
inst = new_instruction(emitInfo, opcode);
}
n->InstLocation = emitInfo->prog->NumInstructions;
inst = new_instruction(emitInfo, opcode);
*/
const GLuint condWritemask = inst->DstReg.WriteMask;
inst = new_instruction(emitInfo, opcode);
*/
const GLuint condWritemask = inst->DstReg.WriteMask;
inst = new_instruction(emitInfo, opcode);
n->InstLocation = emitInfo->prog->NumInstructions;
inst = new_instruction(emitInfo, opcode);
n->InstLocation = emitInfo->prog->NumInstructions;
inst = new_instruction(emitInfo, opcode);
const GLuint condWritemask = inst->DstReg.WriteMask;
assert(emitInfo->EmitCondCodes);
inst = new_instruction(emitInfo, OPCODE_BRA);
const GLuint condWritemask = inst->DstReg.WriteMask;
assert(emitInfo->EmitCondCodes);
inst = new_instruction(emitInfo, OPCODE_BRA);
indexStore, /* the index */
&indirectArray, /* indirect array base */
NULL);
indexStore, /* the index */
&indirectArray, /* indirect array base */
NULL);
_mesa_snprintf(s, sizeof(s), "Undefined variable '%s'",
(char *) n->Var->a_name);
slang_info_log_error(emitInfo->log, s);
_mesa_snprintf(s, sizeof(s), "Undefined variable '%s'",
(char *) n->Var->a_name);
slang_info_log_error(emitInfo->log, s);
if (withEnd) {
struct prog_instruction *inst;
inst = new_instruction(&emitInfo, OPCODE_END);
if (withEnd) {
struct prog_instruction *inst;
inst = new_instruction(&emitInfo, OPCODE_END);