st/mesa, glsl_to_tgsi: support glBitmap with a GLSL fragment shader active

This commit is contained in:
Bryan Cain
2011-07-10 17:17:38 -05:00
parent c0dcab2882
commit 5f0b4b0e9d
3 changed files with 105 additions and 6 deletions
+29 -6
View File
@@ -172,6 +172,23 @@ make_bitmap_fragment_program(struct gl_context *ctx, GLuint samplerIndex)
}
static struct gl_program *
make_bitmap_fragment_program_glsl(struct st_context *st,
struct st_fragment_program *orig,
GLuint samplerIndex)
{
struct gl_context *ctx = st->ctx;
struct st_fragment_program *fp = (struct st_fragment_program *)
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
if (!fp)
return NULL;
get_bitmap_visitor(fp, orig->glsl_to_tgsi, samplerIndex);
return &fp->Base.Base;
}
static int
find_free_bit(uint bitfield)
{
@@ -199,6 +216,7 @@ st_make_bitmap_fragment_program(struct st_context *st,
GLuint *bitmap_sampler)
{
struct st_fragment_program *bitmap_prog;
struct st_fragment_program *stfpIn = (struct st_fragment_program *) fpIn;
struct gl_program *newProg;
uint sampler;
@@ -207,13 +225,18 @@ st_make_bitmap_fragment_program(struct st_context *st,
* with the bitmap sampler/kill instructions.
*/
sampler = find_free_bit(fpIn->Base.SamplersUsed);
bitmap_prog = make_bitmap_fragment_program(st->ctx, sampler);
if (stfpIn->glsl_to_tgsi)
newProg = make_bitmap_fragment_program_glsl(st, stfpIn, sampler);
else {
bitmap_prog = make_bitmap_fragment_program(st->ctx, sampler);
newProg = _mesa_combine_programs(st->ctx,
&bitmap_prog->Base.Base,
&fpIn->Base);
/* done with this after combining */
st_reference_fragprog(st, &bitmap_prog, NULL);
newProg = _mesa_combine_programs(st->ctx,
&bitmap_prog->Base.Base,
&fpIn->Base);
/* done with this after combining */
st_reference_fragprog(st, &bitmap_prog, NULL);
}
#if 0
{
@@ -3620,6 +3620,79 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
fp->glsl_to_tgsi = v;
}
/**
* Make fragment program for glBitmap:
* Sample the texture and kill the fragment if the bit is 0.
* This program will be combined with the user's fragment program.
*
* Based on make_bitmap_fragment_program in st_cb_bitmap.c.
*/
extern "C" void
get_bitmap_visitor(struct st_fragment_program *fp,
glsl_to_tgsi_visitor *original, int samplerIndex)
{
glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor();
struct st_context *st = st_context(original->ctx);
struct gl_program *prog = &fp->Base.Base;
st_src_reg coord, src0;
st_dst_reg dst0;
glsl_to_tgsi_instruction *inst;
/* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */
v->ctx = original->ctx;
v->prog = prog;
v->glsl_version = original->glsl_version;
v->options = original->options;
v->next_temp = original->next_temp;
v->num_address_regs = original->num_address_regs;
v->samplers_used = prog->SamplersUsed = original->samplers_used;
v->indirect_addr_temps = original->indirect_addr_temps;
v->indirect_addr_consts = original->indirect_addr_consts;
/* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */
coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type);
src0 = v->get_temp(glsl_type::vec4_type);
dst0 = st_dst_reg(src0);
inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord);
inst->sampler = samplerIndex;
inst->tex_target = TEXTURE_2D_INDEX;
prog->InputsRead |= (1 << FRAG_ATTRIB_TEX0);
prog->SamplersUsed |= (1 << samplerIndex); /* mark sampler as used */
v->samplers_used |= (1 << samplerIndex);
/* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */
src0.negate = NEGATE_XYZW;
if (st->bitmap.tex_format == PIPE_FORMAT_L8_UNORM)
src0.swizzle = SWIZZLE_XXXX;
inst = v->emit(NULL, TGSI_OPCODE_KIL, undef_dst, src0);
/* Now copy the instructions from the original glsl_to_tgsi_visitor into the
* new visitor. */
foreach_iter(exec_list_iterator, iter, original->instructions) {
glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
st_src_reg src_regs[3];
if (inst->dst.file == PROGRAM_OUTPUT)
prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index);
for (int i=0; i<3; i++) {
src_regs[i] = inst->src[i];
if (src_regs[i].file == PROGRAM_INPUT)
prog->InputsRead |= (1 << src_regs[i].index);
}
v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]);
}
/* Make modifications to fragment program info. */
prog->Parameters = _mesa_clone_parameter_list(original->prog->Parameters);
prog->Attributes = _mesa_clone_parameter_list(original->prog->Attributes);
prog->Varying = _mesa_clone_parameter_list(original->prog->Varying);
count_resources(v, prog);
fp->glsl_to_tgsi = v;
}
/* ------------------------- TGSI conversion stuff -------------------------- */
struct label {
unsigned branch_target;
+3
View File
@@ -55,6 +55,9 @@ void free_glsl_to_tgsi_visitor(struct glsl_to_tgsi_visitor *v);
void get_pixel_transfer_visitor(struct st_fragment_program *fp,
struct glsl_to_tgsi_visitor *original,
int scale_and_bias, int pixel_maps);
void get_bitmap_visitor(struct st_fragment_program *fp,
struct glsl_to_tgsi_visitor *original,
int samplerIndex);
struct gl_shader *st_new_shader(struct gl_context *ctx, GLuint name, GLuint type);