util: assorted updates to polygon stipple helper

This commit is contained in:
Brian Paul 2011-07-21 09:55:22 -06:00
parent 4736c0ba86
commit 3dde6be908
1 changed files with 33 additions and 10 deletions

View File

@ -52,6 +52,7 @@
#include "tgsi/tgsi_transform.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_scan.h"
/** Approx number of new tokens for instructions in pstip_transform_inst() */
#define NUM_NEW_TOKENS 50
@ -175,6 +176,7 @@ util_pstipple_create_sampler(struct pipe_context *pipe)
*/
struct pstip_transform_context {
struct tgsi_transform_context base;
struct tgsi_shader_info info;
uint tempsUsed; /**< bitmask */
int wincoordInput;
int maxInput;
@ -183,12 +185,13 @@ struct pstip_transform_context {
int texTemp; /**< temp registers */
int numImmed;
boolean firstInstruction;
uint coordOrigin;
};
/**
* TGSI declaration transform callback.
* Look for a free sampler, a free input attrib, and two free temp regs.
* Track samplers used, temps used, inputs used.
*/
static void
pstip_transform_decl(struct tgsi_transform_context *ctx,
@ -197,10 +200,11 @@ pstip_transform_decl(struct tgsi_transform_context *ctx,
struct pstip_transform_context *pctx =
(struct pstip_transform_context *) ctx;
/* XXX we can use tgsi_shader_info instead of some of this */
if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
uint i;
for (i = decl->Range.First;
i <= decl->Range.Last; i++) {
for (i = decl->Range.First; i <= decl->Range.Last; i++) {
pctx->samplersUsed |= 1 << i;
}
}
@ -211,8 +215,7 @@ pstip_transform_decl(struct tgsi_transform_context *ctx,
}
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
uint i;
for (i = decl->Range.First;
i <= decl->Range.Last; i++) {
for (i = decl->Range.First; i <= decl->Range.Last; i++) {
pctx->tempsUsed |= (1 << i);
}
}
@ -243,8 +246,16 @@ 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.
* Before the first instruction, insert our new code to sample the
* stipple texture (using the fragment coord register) then kill the
* fragment if the stipple texture bit is off.
*
* Insert:
* declare new registers
* MUL texTemp, INPUT[wincoord], 1/32;
* TEX texTemp, texTemp, sampler;
* KIL -texTemp; # if -texTemp < 0, KILL fragment
* [...original code...]
*/
static void
pstip_transform_inst(struct tgsi_transform_context *ctx,
@ -261,7 +272,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
uint i;
int wincoordInput;
/* find free sampler */
/* find free texture sampler */
pctx->freeSampler = free_bit(pctx->samplersUsed);
if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
@ -271,7 +282,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
else
wincoordInput = pctx->wincoordInput;
/* find one free temp reg */
/* find one free temp register */
for (i = 0; i < 32; i++) {
if ((pctx->tempsUsed & (1 << i)) == 0) {
/* found a free temp */
@ -397,6 +408,7 @@ util_pstipple_create_fragment_shader(struct pipe_context *pipe,
struct pipe_shader_state *new_fs;
struct pstip_transform_context transform;
const uint newLen = tgsi_num_tokens(fs->tokens) + NUM_NEW_TOKENS;
unsigned i;
new_fs = MALLOC(sizeof(*new_fs));
if (!new_fs)
@ -408,22 +420,33 @@ util_pstipple_create_fragment_shader(struct pipe_context *pipe,
return NULL;
}
/* Setup shader transformation info/context.
*/
memset(&transform, 0, sizeof(transform));
transform.wincoordInput = -1;
transform.maxInput = -1;
transform.texTemp = -1;
transform.firstInstruction = TRUE;
transform.coordOrigin = TGSI_FS_COORD_ORIGIN_UPPER_LEFT;
transform.base.transform_instruction = pstip_transform_inst;
transform.base.transform_declaration = pstip_transform_decl;
transform.base.transform_immediate = pstip_transform_immed;
tgsi_scan_shader(fs->tokens, &transform.info);
/* find fragment coordinate origin property */
for (i = 0; i < transform.info.num_properties; i++) {
if (transform.info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN)
transform.coordOrigin = transform.info.properties[i].data[0];
}
tgsi_transform_shader(fs->tokens,
(struct tgsi_token *) new_fs->tokens,
newLen, &transform.base);
#if 0 /* DEBUG */
tgsi_dump(fs->tokens, 0);
tgsi_dump(pstip_fs.tokens, 0);
tgsi_dump(new_fs->tokens, 0);
#endif
assert(transform.freeSampler < PIPE_MAX_SAMPLERS);