/** * Upload the pixel transfer color map texture. */ static void update_pixel_transfer(struct st_context *st) { struct gl_context *ctx = st->ctx; if (ctx->Pixel.MapColorFlag) { /* create the colormap/texture now if not already done */ if (!st->pixel_xfer.pixelmap_texture) { st->pixel_xfer.pixelmap_texture = st_create_color_map_texture(ctx); st->pixel_xfer.pixelmap_sampler_view = st_create_texture_sampler_view(st->pipe, st->pixel_xfer.pixelmap_texture); } load_color_map_texture(ctx, st->pixel_xfer.pixelmap_texture); } }
/** * Returns a fragment program which implements the current pixel transfer ops. */ static struct gl_fragment_program * get_pixel_transfer_program(struct gl_context *ctx, const struct state_key *key) { struct st_context *st = st_context(ctx); struct prog_instruction inst[MAX_INST]; struct gl_program_parameter_list *params; struct gl_fragment_program *fp; GLuint ic = 0; const GLuint colorTemp = 0; fp = (struct gl_fragment_program *) ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!fp) return NULL; params = _mesa_new_parameter_list(); /* * Get initial pixel color from the texture. * TEX colorTemp, fragment.texcoord[0], texture[0], 2D; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_TEX; inst[ic].DstReg.File = PROGRAM_TEMPORARY; inst[ic].DstReg.Index = colorTemp; inst[ic].SrcReg[0].File = PROGRAM_INPUT; inst[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0; inst[ic].TexSrcUnit = 0; inst[ic].TexSrcTarget = TEXTURE_2D_INDEX; ic++; fp->Base.InputsRead = BITFIELD64_BIT(FRAG_ATTRIB_TEX0); fp->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR); fp->Base.SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ if (key->scaleAndBias) { static const gl_state_index scale_state[STATE_LENGTH] = { STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 }; static const gl_state_index bias_state[STATE_LENGTH] = { STATE_INTERNAL, STATE_PT_BIAS, 0, 0, 0 }; GLint scale_p, bias_p; scale_p = _mesa_add_state_reference(params, scale_state); bias_p = _mesa_add_state_reference(params, bias_state); /* MAD colorTemp, colorTemp, scale, bias; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_MAD; inst[ic].DstReg.File = PROGRAM_TEMPORARY; inst[ic].DstReg.Index = colorTemp; inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; inst[ic].SrcReg[0].Index = colorTemp; inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; inst[ic].SrcReg[1].Index = scale_p; inst[ic].SrcReg[2].File = PROGRAM_STATE_VAR; inst[ic].SrcReg[2].Index = bias_p; ic++; } if (key->pixelMaps) { const GLuint temp = 1; /* create the colormap/texture now if not already done */ if (!st->pixel_xfer.pixelmap_texture) { st->pixel_xfer.pixelmap_texture = st_create_color_map_texture(ctx); st->pixel_xfer.pixelmap_sampler_view = st_create_texture_sampler_view(st->pipe, st->pixel_xfer.pixelmap_texture); } /* with a little effort, we can do four pixel map look-ups with * two TEX instructions: */ /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_TEX; inst[ic].DstReg.File = PROGRAM_TEMPORARY; inst[ic].DstReg.Index = temp; inst[ic].DstReg.WriteMask = WRITEMASK_XY; /* write R,G */ inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; inst[ic].SrcReg[0].Index = colorTemp; inst[ic].TexSrcUnit = 1; inst[ic].TexSrcTarget = TEXTURE_2D_INDEX; ic++; /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_TEX; inst[ic].DstReg.File = PROGRAM_TEMPORARY; inst[ic].DstReg.Index = temp; inst[ic].DstReg.WriteMask = WRITEMASK_ZW; /* write B,A */ inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; inst[ic].SrcReg[0].Index = colorTemp; inst[ic].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W); inst[ic].TexSrcUnit = 1; inst[ic].TexSrcTarget = TEXTURE_2D_INDEX; ic++; /* MOV colorTemp, temp; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_MOV; inst[ic].DstReg.File = PROGRAM_TEMPORARY; inst[ic].DstReg.Index = colorTemp; inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; inst[ic].SrcReg[0].Index = temp; ic++; fp->Base.SamplersUsed |= (1 << 1); /* sampler 1 is used */ } /* Modify last instruction's dst reg to write to result.color */ { struct prog_instruction *last = &inst[ic - 1]; last->DstReg.File = PROGRAM_OUTPUT; last->DstReg.Index = FRAG_RESULT_COLOR; } /* END; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_END; ic++; assert(ic <= MAX_INST); fp->Base.Instructions = _mesa_alloc_instructions(ic); if (!fp->Base.Instructions) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating pixel transfer program"); _mesa_free_parameter_list(params); return NULL; } _mesa_copy_instructions(fp->Base.Instructions, inst, ic); fp->Base.NumInstructions = ic; fp->Base.Parameters = params; #if 0 printf("========= pixel transfer prog\n"); _mesa_print_program(&fp->Base); _mesa_print_parameter_list(fp->Base.Parameters); #endif return fp; }