st/mesa, glsl_to_tgsi: support glBitmap with a GLSL fragment shader active
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user