Go to the source code of this file.
Data Structures | |
struct | state_key |
Defines | |
#define | MAX_INST 100 |
Functions | |
static GLboolean | is_identity (const GLfloat m[16]) |
static void | make_state_key (GLcontext *ctx, struct state_key *key) |
static struct pipe_texture * | create_color_map_texture (GLcontext *ctx) |
static void | load_color_map_texture (GLcontext *ctx, struct pipe_texture *pt) |
Update the pixelmap texture with the contents of the R/G/B/A pixel maps. | |
static struct gl_fragment_program * | get_pixel_transfer_program (GLcontext *ctx, const struct state_key *key) |
Returns a fragment program which implements the current pixel transfer ops. | |
static void | update_pixel_transfer (struct st_context *st) |
Update st->pixel_xfer.program in response to new pixel-transfer state. | |
Variables | |
struct st_tracked_state | st_update_pixel_transfer |
#define MAX_INST 100 |
Definition at line 180 of file st_atom_pixeltransfer.c.
static struct pipe_texture* create_color_map_texture | ( | GLcontext * | ctx | ) | [static, read] |
Definition at line 117 of file st_atom_pixeltransfer.c.
References pipe_texture::format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, st_choose_format(), and st_texture_create().
00118 { 00119 struct pipe_context *pipe = ctx->st->pipe; 00120 struct pipe_texture *pt; 00121 enum pipe_format format; 00122 const uint texSize = 256; /* simple, and usually perfect */ 00123 00124 /* find an RGBA texture format */ 00125 format = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER); 00126 00127 /* create texture for color map/table */ 00128 pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, 00129 texSize, texSize, 1, 0, 00130 PIPE_TEXTURE_USAGE_SAMPLER); 00131 return pt; 00132 }
static struct gl_fragment_program* get_pixel_transfer_program | ( | GLcontext * | ctx, | |
const struct state_key * | key | |||
) | [static, read] |
Returns a fragment program which implements the current pixel transfer ops.
Definition at line 186 of file st_atom_pixeltransfer.c.
References assert, state_key::colorMatrix, state_key::colorMatrixPostScaleBias, create_color_map_texture(), st_context::pixel_xfer, st_context::pixelmap_texture, state_key::pixelMaps, and state_key::scaleAndBias.
00187 { 00188 struct st_context *st = ctx->st; 00189 struct prog_instruction inst[MAX_INST]; 00190 struct gl_program_parameter_list *params; 00191 struct gl_fragment_program *fp; 00192 GLuint ic = 0; 00193 const GLuint colorTemp = 0; 00194 00195 fp = (struct gl_fragment_program *) 00196 ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 00197 if (!fp) 00198 return NULL; 00199 00200 params = _mesa_new_parameter_list(); 00201 00202 /* 00203 * Get initial pixel color from the texture. 00204 * TEX colorTemp, fragment.texcoord[0], texture[0], 2D; 00205 */ 00206 _mesa_init_instructions(inst + ic, 1); 00207 inst[ic].Opcode = OPCODE_TEX; 00208 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00209 inst[ic].DstReg.Index = colorTemp; 00210 inst[ic].SrcReg[0].File = PROGRAM_INPUT; 00211 inst[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0; 00212 inst[ic].TexSrcUnit = 0; 00213 inst[ic].TexSrcTarget = TEXTURE_2D_INDEX; 00214 ic++; 00215 fp->Base.InputsRead = (1 << FRAG_ATTRIB_TEX0); 00216 fp->Base.OutputsWritten = (1 << FRAG_RESULT_COLR); 00217 fp->Base.SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ 00218 00219 if (key->scaleAndBias) { 00220 static const gl_state_index scale_state[STATE_LENGTH] = 00221 { STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 }; 00222 static const gl_state_index bias_state[STATE_LENGTH] = 00223 { STATE_INTERNAL, STATE_PT_BIAS, 0, 0, 0 }; 00224 GLfloat scale[4], bias[4]; 00225 GLint scale_p, bias_p; 00226 00227 scale[0] = ctx->Pixel.RedScale; 00228 scale[1] = ctx->Pixel.GreenScale; 00229 scale[2] = ctx->Pixel.BlueScale; 00230 scale[3] = ctx->Pixel.AlphaScale; 00231 bias[0] = ctx->Pixel.RedBias; 00232 bias[1] = ctx->Pixel.GreenBias; 00233 bias[2] = ctx->Pixel.BlueBias; 00234 bias[3] = ctx->Pixel.AlphaBias; 00235 00236 scale_p = _mesa_add_state_reference(params, scale_state); 00237 bias_p = _mesa_add_state_reference(params, bias_state); 00238 00239 /* MAD colorTemp, colorTemp, scale, bias; */ 00240 _mesa_init_instructions(inst + ic, 1); 00241 inst[ic].Opcode = OPCODE_MAD; 00242 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00243 inst[ic].DstReg.Index = colorTemp; 00244 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00245 inst[ic].SrcReg[0].Index = colorTemp; 00246 inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; 00247 inst[ic].SrcReg[1].Index = scale_p; 00248 inst[ic].SrcReg[2].File = PROGRAM_STATE_VAR; 00249 inst[ic].SrcReg[2].Index = bias_p; 00250 ic++; 00251 } 00252 00253 if (key->pixelMaps) { 00254 const GLuint temp = 1; 00255 00256 /* create the colormap/texture now if not already done */ 00257 if (!st->pixel_xfer.pixelmap_texture) { 00258 st->pixel_xfer.pixelmap_texture = create_color_map_texture(ctx); 00259 } 00260 00261 /* with a little effort, we can do four pixel map look-ups with 00262 * two TEX instructions: 00263 */ 00264 00265 /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */ 00266 _mesa_init_instructions(inst + ic, 1); 00267 inst[ic].Opcode = OPCODE_TEX; 00268 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00269 inst[ic].DstReg.Index = temp; 00270 inst[ic].DstReg.WriteMask = WRITEMASK_XY; /* write R,G */ 00271 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00272 inst[ic].SrcReg[0].Index = colorTemp; 00273 inst[ic].TexSrcUnit = 1; 00274 inst[ic].TexSrcTarget = TEXTURE_2D_INDEX; 00275 ic++; 00276 00277 /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */ 00278 _mesa_init_instructions(inst + ic, 1); 00279 inst[ic].Opcode = OPCODE_TEX; 00280 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00281 inst[ic].DstReg.Index = temp; 00282 inst[ic].DstReg.WriteMask = WRITEMASK_ZW; /* write B,A */ 00283 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00284 inst[ic].SrcReg[0].Index = colorTemp; 00285 inst[ic].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, 00286 SWIZZLE_Z, SWIZZLE_W); 00287 inst[ic].TexSrcUnit = 1; 00288 inst[ic].TexSrcTarget = TEXTURE_2D_INDEX; 00289 ic++; 00290 00291 /* MOV colorTemp, temp; */ 00292 _mesa_init_instructions(inst + ic, 1); 00293 inst[ic].Opcode = OPCODE_MOV; 00294 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00295 inst[ic].DstReg.Index = colorTemp; 00296 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00297 inst[ic].SrcReg[0].Index = temp; 00298 ic++; 00299 00300 fp->Base.SamplersUsed |= (1 << 1); /* sampler 1 is used */ 00301 } 00302 00303 if (key->colorMatrix) { 00304 static const gl_state_index row0_state[STATE_LENGTH] = 00305 { STATE_COLOR_MATRIX, 0, 0, 0, 0 }; 00306 static const gl_state_index row1_state[STATE_LENGTH] = 00307 { STATE_COLOR_MATRIX, 0, 1, 1, 0 }; 00308 static const gl_state_index row2_state[STATE_LENGTH] = 00309 { STATE_COLOR_MATRIX, 0, 2, 2, 0 }; 00310 static const gl_state_index row3_state[STATE_LENGTH] = 00311 { STATE_COLOR_MATRIX, 0, 3, 3, 0 }; 00312 00313 GLint row0_p = _mesa_add_state_reference(params, row0_state); 00314 GLint row1_p = _mesa_add_state_reference(params, row1_state); 00315 GLint row2_p = _mesa_add_state_reference(params, row2_state); 00316 GLint row3_p = _mesa_add_state_reference(params, row3_state); 00317 const GLuint temp = 1; 00318 00319 /* DP4 temp.x, colorTemp, matrow0; */ 00320 _mesa_init_instructions(inst + ic, 1); 00321 inst[ic].Opcode = OPCODE_DP4; 00322 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00323 inst[ic].DstReg.Index = temp; 00324 inst[ic].DstReg.WriteMask = WRITEMASK_X; 00325 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00326 inst[ic].SrcReg[0].Index = colorTemp; 00327 inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; 00328 inst[ic].SrcReg[1].Index = row0_p; 00329 ic++; 00330 00331 /* DP4 temp.y, colorTemp, matrow1; */ 00332 _mesa_init_instructions(inst + ic, 1); 00333 inst[ic].Opcode = OPCODE_DP4; 00334 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00335 inst[ic].DstReg.Index = temp; 00336 inst[ic].DstReg.WriteMask = WRITEMASK_Y; 00337 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00338 inst[ic].SrcReg[0].Index = colorTemp; 00339 inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; 00340 inst[ic].SrcReg[1].Index = row1_p; 00341 ic++; 00342 00343 /* DP4 temp.z, colorTemp, matrow2; */ 00344 _mesa_init_instructions(inst + ic, 1); 00345 inst[ic].Opcode = OPCODE_DP4; 00346 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00347 inst[ic].DstReg.Index = temp; 00348 inst[ic].DstReg.WriteMask = WRITEMASK_Z; 00349 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00350 inst[ic].SrcReg[0].Index = colorTemp; 00351 inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; 00352 inst[ic].SrcReg[1].Index = row2_p; 00353 ic++; 00354 00355 /* DP4 temp.w, colorTemp, matrow3; */ 00356 _mesa_init_instructions(inst + ic, 1); 00357 inst[ic].Opcode = OPCODE_DP4; 00358 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00359 inst[ic].DstReg.Index = temp; 00360 inst[ic].DstReg.WriteMask = WRITEMASK_W; 00361 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00362 inst[ic].SrcReg[0].Index = colorTemp; 00363 inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; 00364 inst[ic].SrcReg[1].Index = row3_p; 00365 ic++; 00366 00367 /* MOV colorTemp, temp; */ 00368 _mesa_init_instructions(inst + ic, 1); 00369 inst[ic].Opcode = OPCODE_MOV; 00370 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00371 inst[ic].DstReg.Index = colorTemp; 00372 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00373 inst[ic].SrcReg[0].Index = temp; 00374 ic++; 00375 } 00376 00377 if (key->colorMatrixPostScaleBias) { 00378 static const gl_state_index scale_state[STATE_LENGTH] = 00379 { STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 }; 00380 static const gl_state_index bias_state[STATE_LENGTH] = 00381 { STATE_INTERNAL, STATE_PT_BIAS, 0, 0, 0 }; 00382 GLint scale_param, bias_param; 00383 00384 scale_param = _mesa_add_state_reference(params, scale_state); 00385 bias_param = _mesa_add_state_reference(params, bias_state); 00386 00387 _mesa_init_instructions(inst + ic, 1); 00388 inst[ic].Opcode = OPCODE_MAD; 00389 inst[ic].DstReg.File = PROGRAM_TEMPORARY; 00390 inst[ic].DstReg.Index = colorTemp; 00391 inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; 00392 inst[ic].SrcReg[0].Index = colorTemp; 00393 inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; 00394 inst[ic].SrcReg[1].Index = scale_param; 00395 inst[ic].SrcReg[2].File = PROGRAM_STATE_VAR; 00396 inst[ic].SrcReg[2].Index = bias_param; 00397 ic++; 00398 } 00399 00400 /* Modify last instruction's dst reg to write to result.color */ 00401 { 00402 struct prog_instruction *last = &inst[ic - 1]; 00403 last->DstReg.File = PROGRAM_OUTPUT; 00404 last->DstReg.Index = FRAG_RESULT_COLR; 00405 } 00406 00407 /* END; */ 00408 _mesa_init_instructions(inst + ic, 1); 00409 inst[ic].Opcode = OPCODE_END; 00410 ic++; 00411 00412 assert(ic <= MAX_INST); 00413 00414 00415 fp->Base.Instructions = _mesa_alloc_instructions(ic); 00416 if (!fp->Base.Instructions) { 00417 _mesa_error(ctx, GL_OUT_OF_MEMORY, 00418 "generating pixel transfer program"); 00419 return NULL; 00420 } 00421 00422 _mesa_copy_instructions(fp->Base.Instructions, inst, ic); 00423 fp->Base.NumInstructions = ic; 00424 fp->Base.Parameters = params; 00425 00426 #if 0 00427 printf("========= pixel transfer prog\n"); 00428 _mesa_print_program(&fp->Base); 00429 _mesa_print_parameter_list(fp->Base.Parameters); 00430 #endif 00431 00432 return fp; 00433 }
static GLboolean is_identity | ( | const GLfloat | m[16] | ) | [static] |
Definition at line 75 of file st_atom_pixeltransfer.c.
00076 { 00077 GLuint i; 00078 for (i = 0; i < 16; i++) { 00079 const int row = i % 4, col = i / 4; 00080 const float val = (GLfloat)(row == col); 00081 if (m[i] != val) 00082 return GL_FALSE; 00083 } 00084 return GL_TRUE; 00085 }
static void load_color_map_texture | ( | GLcontext * | ctx, | |
struct pipe_texture * | pt | |||
) | [static] |
Update the pixelmap texture with the contents of the R/G/B/A pixel maps.
Definition at line 139 of file st_atom_pixeltransfer.c.
References pipe_texture::format, pipe_screen::get_tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE, pipe_surface_reference(), pipe_context::screen, pipe_screen::surface_map, pipe_screen::surface_unmap, util_pack_color_ub(), and pipe_texture::width.
00140 { 00141 struct pipe_context *pipe = ctx->st->pipe; 00142 struct pipe_screen *screen = pipe->screen; 00143 struct pipe_surface *surface; 00144 const GLuint rSize = ctx->PixelMaps.RtoR.Size; 00145 const GLuint gSize = ctx->PixelMaps.GtoG.Size; 00146 const GLuint bSize = ctx->PixelMaps.BtoB.Size; 00147 const GLuint aSize = ctx->PixelMaps.AtoA.Size; 00148 const uint texSize = pt->width[0]; 00149 uint *dest; 00150 uint i, j; 00151 00152 surface = screen->get_tex_surface(screen, pt, 0, 0, 0, 00153 PIPE_BUFFER_USAGE_CPU_WRITE); 00154 dest = (uint *) screen->surface_map(screen, surface, 00155 PIPE_BUFFER_USAGE_CPU_WRITE); 00156 00157 /* Pack four 1D maps into a 2D texture: 00158 * R map is placed horizontally, indexed by S, in channel 0 00159 * G map is placed vertically, indexed by T, in channel 1 00160 * B map is placed horizontally, indexed by S, in channel 2 00161 * A map is placed vertically, indexed by T, in channel 3 00162 */ 00163 for (i = 0; i < texSize; i++) { 00164 for (j = 0; j < texSize; j++) { 00165 int k = (i * texSize + j); 00166 ubyte r = ctx->PixelMaps.RtoR.Map8[j * rSize / texSize]; 00167 ubyte g = ctx->PixelMaps.GtoG.Map8[i * gSize / texSize]; 00168 ubyte b = ctx->PixelMaps.BtoB.Map8[j * bSize / texSize]; 00169 ubyte a = ctx->PixelMaps.AtoA.Map8[i * aSize / texSize]; 00170 util_pack_color_ub(r, g, b, a, pt->format, dest + k); 00171 } 00172 } 00173 00174 screen->surface_unmap(screen, surface); 00175 pipe_surface_reference(&surface, NULL); 00176 }
static void make_state_key | ( | GLcontext * | ctx, | |
struct state_key * | key | |||
) | [static] |
Definition at line 89 of file st_atom_pixeltransfer.c.
References state_key::colorMatrix, state_key::colorMatrixPostScaleBias, is_identity(), state_key::pixelMaps, and state_key::scaleAndBias.
00090 { 00091 static const GLfloat zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; 00092 static const GLfloat one[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; 00093 00094 memset(key, 0, sizeof(*key)); 00095 00096 if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 || 00097 ctx->Pixel.GreenBias != 0.0 || ctx->Pixel.GreenScale != 1.0 || 00098 ctx->Pixel.BlueBias != 0.0 || ctx->Pixel.BlueScale != 1.0 || 00099 ctx->Pixel.AlphaBias != 0.0 || ctx->Pixel.AlphaScale != 1.0) { 00100 key->scaleAndBias = 1; 00101 } 00102 00103 if (!is_identity(ctx->ColorMatrixStack.Top->m)) { 00104 key->colorMatrix = 1; 00105 } 00106 00107 if (!TEST_EQ_4V(ctx->Pixel.PostColorMatrixScale, one) || 00108 !TEST_EQ_4V(ctx->Pixel.PostColorMatrixBias, zero)) { 00109 key->colorMatrixPostScaleBias = 1; 00110 } 00111 00112 key->pixelMaps = ctx->Pixel.MapColorFlag; 00113 }
static void update_pixel_transfer | ( | struct st_context * | st | ) | [static] |
Update st->pixel_xfer.program in response to new pixel-transfer state.
Definition at line 441 of file st_atom_pixeltransfer.c.
References st_context::cache, st_context::ctx, get_pixel_transfer_program(), load_color_map_texture(), make_state_key(), st_context::pixel_xfer, st_context::pixelmap_enabled, st_context::pixelmap_texture, and st_context::program.
00442 { 00443 GLcontext *ctx = st->ctx; 00444 struct state_key key; 00445 struct gl_fragment_program *fp; 00446 00447 make_state_key(st->ctx, &key); 00448 00449 fp = (struct gl_fragment_program *) 00450 _mesa_search_program_cache(st->pixel_xfer.cache, &key, sizeof(key)); 00451 if (!fp) { 00452 fp = get_pixel_transfer_program(st->ctx, &key); 00453 _mesa_program_cache_insert(st->ctx, st->pixel_xfer.cache, 00454 &key, sizeof(key), &fp->Base); 00455 } 00456 00457 if (ctx->Pixel.MapColorFlag) { 00458 load_color_map_texture(ctx, st->pixel_xfer.pixelmap_texture); 00459 } 00460 st->pixel_xfer.pixelmap_enabled = ctx->Pixel.MapColorFlag; 00461 00462 st->pixel_xfer.program = (struct st_fragment_program *) fp; 00463 }
Initial value:
{ "st_update_pixel_transfer", { _NEW_PIXEL | _NEW_COLOR_MATRIX, 0, }, update_pixel_transfer }
Definition at line 467 of file st_atom_pixeltransfer.c.