st_atom_pixeltransfer.c File Reference

Include dependency graph for st_atom_pixeltransfer.c:

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_texturecreate_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 Documentation

#define MAX_INST   100

Definition at line 180 of file st_atom_pixeltransfer.c.


Function Documentation

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 }


Variable Documentation

struct st_tracked_state st_update_pixel_transfer

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.


Generated on Tue Sep 29 06:25:51 2009 for Gallium3D by  doxygen 1.5.4