draw: use tgsi transform prolog callback in polygon stipple code

Reviewed-by: Charmaine Lee <charmainel@vmware.com>
This commit is contained in:
Brian Paul
2014-09-19 13:24:20 -06:00
parent 6581aa441e
commit 16ff2fdd70
+111 -126
View File
@@ -129,7 +129,6 @@ struct pstip_transform_context {
int freeSampler; /** an available sampler for the pstipple */
int texTemp; /**< temp registers */
int numImmed;
boolean firstInstruction;
};
@@ -192,147 +191,134 @@ free_bit(uint bitfield)
/**
* TGSI instruction transform callback.
* Replace writes to result.color w/ a temp reg.
* Upon END instruction, insert texture sampling code for antialiasing.
* TGSI transform prolog callback.
*/
static void
pstip_transform_inst(struct tgsi_transform_context *ctx,
struct tgsi_full_instruction *inst)
pstip_transform_prolog(struct tgsi_transform_context *ctx)
{
struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
struct tgsi_full_declaration decl;
struct tgsi_full_instruction newInst;
uint i;
int wincoordInput;
if (pctx->firstInstruction) {
/* emit our new declarations before the first instruction */
/* find free sampler */
pctx->freeSampler = free_bit(pctx->samplersUsed);
if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
struct tgsi_full_declaration decl;
struct tgsi_full_instruction newInst;
uint i;
int wincoordInput;
if (pctx->wincoordInput < 0)
wincoordInput = pctx->maxInput + 1;
else
wincoordInput = pctx->wincoordInput;
/* find free sampler */
pctx->freeSampler = free_bit(pctx->samplersUsed);
if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
if (pctx->wincoordInput < 0)
wincoordInput = pctx->maxInput + 1;
/* find one free temp reg */
for (i = 0; i < 32; i++) {
if ((pctx->tempsUsed & (1 << i)) == 0) {
/* found a free temp */
if (pctx->texTemp < 0)
pctx->texTemp = i;
else
wincoordInput = pctx->wincoordInput;
/* find one free temp reg */
for (i = 0; i < 32; i++) {
if ((pctx->tempsUsed & (1 << i)) == 0) {
/* found a free temp */
if (pctx->texTemp < 0)
pctx->texTemp = i;
else
break;
}
break;
}
assert(pctx->texTemp >= 0);
}
assert(pctx->texTemp >= 0);
if (pctx->wincoordInput < 0) {
/* declare new position input reg */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
decl.Declaration.Interpolate = 1;
decl.Declaration.Semantic = 1;
decl.Semantic.Name = TGSI_SEMANTIC_POSITION;
decl.Semantic.Index = 0;
decl.Range.First =
decl.Range.Last = wincoordInput;
decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
ctx->emit_declaration(ctx, &decl);
}
/* declare new sampler */
if (pctx->wincoordInput < 0) {
/* declare new position input reg */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
decl.Declaration.File = TGSI_FILE_INPUT;
decl.Declaration.Interpolate = 1;
decl.Declaration.Semantic = 1;
decl.Semantic.Name = TGSI_SEMANTIC_POSITION;
decl.Semantic.Index = 0;
decl.Range.First =
decl.Range.Last = pctx->freeSampler;
decl.Range.Last = wincoordInput;
decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
ctx->emit_declaration(ctx, &decl);
/* declare new temp regs */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
decl.Range.First =
decl.Range.Last = pctx->texTemp;
ctx->emit_declaration(ctx, &decl);
/* emit immediate = {1/32, 1/32, 1, 1}
* The index/position of this immediate will be pctx->numImmed
*/
{
static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 };
struct tgsi_full_immediate immed;
uint size = 4;
immed = tgsi_default_full_immediate();
immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
immed.u[0].Float = value[0];
immed.u[1].Float = value[1];
immed.u[2].Float = value[2];
immed.u[3].Float = value[3];
ctx->emit_immediate(ctx, &immed);
}
pctx->firstInstruction = FALSE;
/*
* Insert new MUL/TEX/KILL_IF instructions at start of program
* Take gl_FragCoord, divide by 32 (stipple size), sample the
* texture and kill fragment if needed.
*
* We'd like to use non-normalized texcoords to index into a RECT
* texture, but we can only use GL_REPEAT wrap mode with normalized
* texcoords. Darn.
*/
/* MUL texTemp, INPUT[wincoord], 1/32; */
newInst = tgsi_default_full_instruction();
newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
newInst.Instruction.NumDstRegs = 1;
newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
newInst.Dst[0].Register.Index = pctx->texTemp;
newInst.Instruction.NumSrcRegs = 2;
newInst.Src[0].Register.File = TGSI_FILE_INPUT;
newInst.Src[0].Register.Index = wincoordInput;
newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE;
newInst.Src[1].Register.Index = pctx->numImmed;
ctx->emit_instruction(ctx, &newInst);
/* TEX texTemp, texTemp, sampler; */
newInst = tgsi_default_full_instruction();
newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
newInst.Instruction.NumDstRegs = 1;
newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
newInst.Dst[0].Register.Index = pctx->texTemp;
newInst.Instruction.NumSrcRegs = 2;
newInst.Instruction.Texture = TRUE;
newInst.Texture.Texture = TGSI_TEXTURE_2D;
newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
newInst.Src[0].Register.Index = pctx->texTemp;
newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
newInst.Src[1].Register.Index = pctx->freeSampler;
ctx->emit_instruction(ctx, &newInst);
/* KILL_IF -texTemp; # if -texTemp < 0, KILL fragment */
newInst = tgsi_default_full_instruction();
newInst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
newInst.Instruction.NumDstRegs = 0;
newInst.Instruction.NumSrcRegs = 1;
newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
newInst.Src[0].Register.Index = pctx->texTemp;
newInst.Src[0].Register.Negate = 1;
ctx->emit_instruction(ctx, &newInst);
}
/* emit this instruction */
ctx->emit_instruction(ctx, inst);
/* declare new sampler */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
decl.Range.First =
decl.Range.Last = pctx->freeSampler;
ctx->emit_declaration(ctx, &decl);
/* declare new temp regs */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
decl.Range.First =
decl.Range.Last = pctx->texTemp;
ctx->emit_declaration(ctx, &decl);
/* emit immediate = {1/32, 1/32, 1, 1}
* The index/position of this immediate will be pctx->numImmed
*/
{
static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 };
struct tgsi_full_immediate immed;
uint size = 4;
immed = tgsi_default_full_immediate();
immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
immed.u[0].Float = value[0];
immed.u[1].Float = value[1];
immed.u[2].Float = value[2];
immed.u[3].Float = value[3];
ctx->emit_immediate(ctx, &immed);
}
/*
* Insert new MUL/TEX/KILL_IF instructions at start of program
* Take gl_FragCoord, divide by 32 (stipple size), sample the
* texture and kill fragment if needed.
*
* We'd like to use non-normalized texcoords to index into a RECT
* texture, but we can only use GL_REPEAT wrap mode with normalized
* texcoords. Darn.
*/
/* MUL texTemp, INPUT[wincoord], 1/32; */
newInst = tgsi_default_full_instruction();
newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
newInst.Instruction.NumDstRegs = 1;
newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
newInst.Dst[0].Register.Index = pctx->texTemp;
newInst.Instruction.NumSrcRegs = 2;
newInst.Src[0].Register.File = TGSI_FILE_INPUT;
newInst.Src[0].Register.Index = wincoordInput;
newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE;
newInst.Src[1].Register.Index = pctx->numImmed;
ctx->emit_instruction(ctx, &newInst);
/* TEX texTemp, texTemp, sampler; */
newInst = tgsi_default_full_instruction();
newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
newInst.Instruction.NumDstRegs = 1;
newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
newInst.Dst[0].Register.Index = pctx->texTemp;
newInst.Instruction.NumSrcRegs = 2;
newInst.Instruction.Texture = TRUE;
newInst.Texture.Texture = TGSI_TEXTURE_2D;
newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
newInst.Src[0].Register.Index = pctx->texTemp;
newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
newInst.Src[1].Register.Index = pctx->freeSampler;
ctx->emit_instruction(ctx, &newInst);
/* KILL_IF -texTemp; # if -texTemp < 0, KILL fragment */
newInst = tgsi_default_full_instruction();
newInst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
newInst.Instruction.NumDstRegs = 0;
newInst.Instruction.NumSrcRegs = 1;
newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
newInst.Src[0].Register.Index = pctx->texTemp;
newInst.Src[0].Register.Negate = 1;
ctx->emit_instruction(ctx, &newInst);
}
/**
* Generate the frag shader we'll use for doing polygon stipple.
* This will be the user's shader prefixed with a TEX and KIL instruction.
@@ -355,8 +341,7 @@ generate_pstip_fs(struct pstip_stage *pstip)
transform.wincoordInput = -1;
transform.maxInput = -1;
transform.texTemp = -1;
transform.firstInstruction = TRUE;
transform.base.transform_instruction = pstip_transform_inst;
transform.base.prolog = pstip_transform_prolog;
transform.base.transform_declaration = pstip_transform_decl;
transform.base.transform_immediate = pstip_transform_immed;