17ce99a11037e577e36480f3e29b2685b853f0330Brian/**************************************************************************
27ce99a11037e577e36480f3e29b2685b853f0330Brian *
37ce99a11037e577e36480f3e29b2685b853f0330Brian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
47ce99a11037e577e36480f3e29b2685b853f0330Brian * All Rights Reserved.
57ce99a11037e577e36480f3e29b2685b853f0330Brian *
67ce99a11037e577e36480f3e29b2685b853f0330Brian * Permission is hereby granted, free of charge, to any person obtaining a
77ce99a11037e577e36480f3e29b2685b853f0330Brian * copy of this software and associated documentation files (the
87ce99a11037e577e36480f3e29b2685b853f0330Brian * "Software"), to deal in the Software without restriction, including
97ce99a11037e577e36480f3e29b2685b853f0330Brian * without limitation the rights to use, copy, modify, merge, publish,
107ce99a11037e577e36480f3e29b2685b853f0330Brian * distribute, sub license, and/or sell copies of the Software, and to
117ce99a11037e577e36480f3e29b2685b853f0330Brian * permit persons to whom the Software is furnished to do so, subject to
127ce99a11037e577e36480f3e29b2685b853f0330Brian * the following conditions:
137ce99a11037e577e36480f3e29b2685b853f0330Brian *
147ce99a11037e577e36480f3e29b2685b853f0330Brian * The above copyright notice and this permission notice (including the
157ce99a11037e577e36480f3e29b2685b853f0330Brian * next paragraph) shall be included in all copies or substantial portions
167ce99a11037e577e36480f3e29b2685b853f0330Brian * of the Software.
177ce99a11037e577e36480f3e29b2685b853f0330Brian *
187ce99a11037e577e36480f3e29b2685b853f0330Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
197ce99a11037e577e36480f3e29b2685b853f0330Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
207ce99a11037e577e36480f3e29b2685b853f0330Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
217ce99a11037e577e36480f3e29b2685b853f0330Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
227ce99a11037e577e36480f3e29b2685b853f0330Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
237ce99a11037e577e36480f3e29b2685b853f0330Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
247ce99a11037e577e36480f3e29b2685b853f0330Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
257ce99a11037e577e36480f3e29b2685b853f0330Brian *
267ce99a11037e577e36480f3e29b2685b853f0330Brian **************************************************************************/
277ce99a11037e577e36480f3e29b2685b853f0330Brian
287ce99a11037e577e36480f3e29b2685b853f0330Brian/*
297ce99a11037e577e36480f3e29b2685b853f0330Brian * Generate fragment programs to implement pixel transfer ops, such as
3073578ba9c4938db3a23198c3a2ddf843cfc4f700Eric Anholt * scale/bias, colortable, convolution...
317ce99a11037e577e36480f3e29b2685b853f0330Brian *
327ce99a11037e577e36480f3e29b2685b853f0330Brian * Authors:
337ce99a11037e577e36480f3e29b2685b853f0330Brian *   Brian Paul
347ce99a11037e577e36480f3e29b2685b853f0330Brian */
357ce99a11037e577e36480f3e29b2685b853f0330Brian
367ce99a11037e577e36480f3e29b2685b853f0330Brian#include "main/imports.h"
377ce99a11037e577e36480f3e29b2685b853f0330Brian#include "main/image.h"
387ce99a11037e577e36480f3e29b2685b853f0330Brian#include "main/macros.h"
39ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/program.h"
40a0989e94374a678fb6c2d0974255a178361c47a7Vinson Lee#include "program/prog_cache.h"
41ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_instruction.h"
42ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_parameter.h"
43ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_print.h"
447ce99a11037e577e36480f3e29b2685b853f0330Brian
457ce99a11037e577e36480f3e29b2685b853f0330Brian#include "st_context.h"
464b822a101680532ce6df52904af91194b78a16baBrian Paul#include "st_format.h"
474b822a101680532ce6df52904af91194b78a16baBrian Paul#include "st_texture.h"
487ce99a11037e577e36480f3e29b2685b853f0330Brian
494b822a101680532ce6df52904af91194b78a16baBrian Paul#include "pipe/p_screen.h"
504b822a101680532ce6df52904af91194b78a16baBrian Paul#include "pipe/p_context.h"
51b0427bedde80e3189524651a327235bdfddbc613José Fonseca#include "util/u_inlines.h"
524b822a101680532ce6df52904af91194b78a16baBrian Paul#include "util/u_pack_color.h"
537ce99a11037e577e36480f3e29b2685b853f0330Brian
548aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
558aa42546add1fef4949e2d4ceded62e2d1dd0215Brianstruct state_key
568aa42546add1fef4949e2d4ceded62e2d1dd0215Brian{
578aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   GLuint scaleAndBias:1;
584b822a101680532ce6df52904af91194b78a16baBrian Paul   GLuint pixelMaps:1;
598aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
608aa42546add1fef4949e2d4ceded62e2d1dd0215Brian#if 0
618aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   GLfloat Maps[3][256][4];
628aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   int NumMaps;
638aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   GLint NumStages;
648aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   pipeline_stage Stages[STAGE_MAX];
658aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   GLboolean StagesUsed[STAGE_MAX];
668aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   GLfloat Scale1[4], Bias1[4];
678aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   GLfloat Scale2[4], Bias2[4];
688aa42546add1fef4949e2d4ceded62e2d1dd0215Brian#endif
698aa42546add1fef4949e2d4ceded62e2d1dd0215Brian};
708aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
718aa42546add1fef4949e2d4ceded62e2d1dd0215Brianstatic void
72f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergmake_state_key(struct gl_context *ctx,  struct state_key *key)
738aa42546add1fef4949e2d4ceded62e2d1dd0215Brian{
748aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   memset(key, 0, sizeof(*key));
758aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
768aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 ||
778aa42546add1fef4949e2d4ceded62e2d1dd0215Brian       ctx->Pixel.GreenBias != 0.0 || ctx->Pixel.GreenScale != 1.0 ||
788aa42546add1fef4949e2d4ceded62e2d1dd0215Brian       ctx->Pixel.BlueBias != 0.0 || ctx->Pixel.BlueScale != 1.0 ||
798aa42546add1fef4949e2d4ceded62e2d1dd0215Brian       ctx->Pixel.AlphaBias != 0.0 || ctx->Pixel.AlphaScale != 1.0) {
808aa42546add1fef4949e2d4ceded62e2d1dd0215Brian      key->scaleAndBias = 1;
818aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   }
828aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
834b822a101680532ce6df52904af91194b78a16baBrian Paul   key->pixelMaps = ctx->Pixel.MapColorFlag;
844b822a101680532ce6df52904af91194b78a16baBrian Paul}
854b822a101680532ce6df52904af91194b78a16baBrian Paul
864b822a101680532ce6df52904af91194b78a16baBrian Paul
874b822a101680532ce6df52904af91194b78a16baBrian Paul/**
884b822a101680532ce6df52904af91194b78a16baBrian Paul * Update the pixelmap texture with the contents of the R/G/B/A pixel maps.
894b822a101680532ce6df52904af91194b78a16baBrian Paul */
904b822a101680532ce6df52904af91194b78a16baBrian Paulstatic void
91f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergload_color_map_texture(struct gl_context *ctx, struct pipe_resource *pt)
924b822a101680532ce6df52904af91194b78a16baBrian Paul{
9376c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
9476c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct pipe_context *pipe = st->pipe;
954617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   struct pipe_transfer *transfer;
964b822a101680532ce6df52904af91194b78a16baBrian Paul   const GLuint rSize = ctx->PixelMaps.RtoR.Size;
974b822a101680532ce6df52904af91194b78a16baBrian Paul   const GLuint gSize = ctx->PixelMaps.GtoG.Size;
984b822a101680532ce6df52904af91194b78a16baBrian Paul   const GLuint bSize = ctx->PixelMaps.BtoB.Size;
994b822a101680532ce6df52904af91194b78a16baBrian Paul   const GLuint aSize = ctx->PixelMaps.AtoA.Size;
100683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   const uint texSize = pt->width0;
1014b822a101680532ce6df52904af91194b78a16baBrian Paul   uint *dest;
1024b822a101680532ce6df52904af91194b78a16baBrian Paul   uint i, j;
1034b822a101680532ce6df52904af91194b78a16baBrian Paul
1043e06803c2c6cf83009708b23d3ebafc0ea3dc525Brian Paul   transfer = pipe_get_transfer(pipe,
1054c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                pt, 0, 0, PIPE_TRANSFER_WRITE,
1064c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                0, 0, texSize, texSize);
107287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   dest = (uint *) pipe_transfer_map(pipe, transfer);
1084b822a101680532ce6df52904af91194b78a16baBrian Paul
1094b822a101680532ce6df52904af91194b78a16baBrian Paul   /* Pack four 1D maps into a 2D texture:
1104b822a101680532ce6df52904af91194b78a16baBrian Paul    * R map is placed horizontally, indexed by S, in channel 0
1114b822a101680532ce6df52904af91194b78a16baBrian Paul    * G map is placed vertically, indexed by T, in channel 1
1124b822a101680532ce6df52904af91194b78a16baBrian Paul    * B map is placed horizontally, indexed by S, in channel 2
1134b822a101680532ce6df52904af91194b78a16baBrian Paul    * A map is placed vertically, indexed by T, in channel 3
1144b822a101680532ce6df52904af91194b78a16baBrian Paul    */
1154b822a101680532ce6df52904af91194b78a16baBrian Paul   for (i = 0; i < texSize; i++) {
1164b822a101680532ce6df52904af91194b78a16baBrian Paul      for (j = 0; j < texSize; j++) {
117ee1720b99dfb5964962f2346406a4e3e88374a68Roland Scheidegger         union util_color uc;
1184b822a101680532ce6df52904af91194b78a16baBrian Paul         int k = (i * texSize + j);
11980fd3d2ca8ae96ebad55c49ed499602e4a669b5aBrian Paul         float rgba[4];
12080fd3d2ca8ae96ebad55c49ed499602e4a669b5aBrian Paul         rgba[0] = ctx->PixelMaps.RtoR.Map[j * rSize / texSize];
12180fd3d2ca8ae96ebad55c49ed499602e4a669b5aBrian Paul         rgba[1] = ctx->PixelMaps.GtoG.Map[i * gSize / texSize];
12280fd3d2ca8ae96ebad55c49ed499602e4a669b5aBrian Paul         rgba[2] = ctx->PixelMaps.BtoB.Map[j * bSize / texSize];
12380fd3d2ca8ae96ebad55c49ed499602e4a669b5aBrian Paul         rgba[3] = ctx->PixelMaps.AtoA.Map[i * aSize / texSize];
12480fd3d2ca8ae96ebad55c49ed499602e4a669b5aBrian Paul         util_pack_color(rgba, pt->format, &uc);
125ee1720b99dfb5964962f2346406a4e3e88374a68Roland Scheidegger         *(dest + k) = uc.ui;
1264b822a101680532ce6df52904af91194b78a16baBrian Paul      }
1274b822a101680532ce6df52904af91194b78a16baBrian Paul   }
1284b822a101680532ce6df52904af91194b78a16baBrian Paul
129287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_transfer_unmap(pipe, transfer);
130287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe->transfer_destroy(pipe, transfer);
131e38f677e8f5596d92a6756e13f41f6523de737c2Brian Paul}
1328aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
1338aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
1348aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
1357ce99a11037e577e36480f3e29b2685b853f0330Brian#define MAX_INST 100
1367ce99a11037e577e36480f3e29b2685b853f0330Brian
1377ce99a11037e577e36480f3e29b2685b853f0330Brian/**
1387ce99a11037e577e36480f3e29b2685b853f0330Brian * Returns a fragment program which implements the current pixel transfer ops.
1397ce99a11037e577e36480f3e29b2685b853f0330Brian */
1407ce99a11037e577e36480f3e29b2685b853f0330Brianstatic struct gl_fragment_program *
141f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergget_pixel_transfer_program(struct gl_context *ctx, const struct state_key *key)
1427ce99a11037e577e36480f3e29b2685b853f0330Brian{
14376c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
1447ce99a11037e577e36480f3e29b2685b853f0330Brian   struct prog_instruction inst[MAX_INST];
1457ce99a11037e577e36480f3e29b2685b853f0330Brian   struct gl_program_parameter_list *params;
1467ce99a11037e577e36480f3e29b2685b853f0330Brian   struct gl_fragment_program *fp;
1477ce99a11037e577e36480f3e29b2685b853f0330Brian   GLuint ic = 0;
148286380020b146d600ac86d519ddfbf765a5965b2Brian   const GLuint colorTemp = 0;
1497ce99a11037e577e36480f3e29b2685b853f0330Brian
1507ce99a11037e577e36480f3e29b2685b853f0330Brian   fp = (struct gl_fragment_program *)
1517ce99a11037e577e36480f3e29b2685b853f0330Brian      ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
1527ce99a11037e577e36480f3e29b2685b853f0330Brian   if (!fp)
1537ce99a11037e577e36480f3e29b2685b853f0330Brian      return NULL;
1547ce99a11037e577e36480f3e29b2685b853f0330Brian
1557ce99a11037e577e36480f3e29b2685b853f0330Brian   params = _mesa_new_parameter_list();
1567ce99a11037e577e36480f3e29b2685b853f0330Brian
1574b822a101680532ce6df52904af91194b78a16baBrian Paul   /*
1584b822a101680532ce6df52904af91194b78a16baBrian Paul    * Get initial pixel color from the texture.
1594b822a101680532ce6df52904af91194b78a16baBrian Paul    * TEX colorTemp, fragment.texcoord[0], texture[0], 2D;
1604b822a101680532ce6df52904af91194b78a16baBrian Paul    */
1617ce99a11037e577e36480f3e29b2685b853f0330Brian   _mesa_init_instructions(inst + ic, 1);
1627ce99a11037e577e36480f3e29b2685b853f0330Brian   inst[ic].Opcode = OPCODE_TEX;
163286380020b146d600ac86d519ddfbf765a5965b2Brian   inst[ic].DstReg.File = PROGRAM_TEMPORARY;
164286380020b146d600ac86d519ddfbf765a5965b2Brian   inst[ic].DstReg.Index = colorTemp;
1657ce99a11037e577e36480f3e29b2685b853f0330Brian   inst[ic].SrcReg[0].File = PROGRAM_INPUT;
1667ce99a11037e577e36480f3e29b2685b853f0330Brian   inst[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
1677ce99a11037e577e36480f3e29b2685b853f0330Brian   inst[ic].TexSrcUnit = 0;
1687ce99a11037e577e36480f3e29b2685b853f0330Brian   inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
1697ce99a11037e577e36480f3e29b2685b853f0330Brian   ic++;
170dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich   fp->Base.InputsRead = BITFIELD64_BIT(FRAG_ATTRIB_TEX0);
171aa878f94ab77fe3be352d820aaa950b32836c814Brian Paul   fp->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR);
17272f2c55069f167a46560005931382e3b472f92edBrian Paul   fp->Base.SamplersUsed = 0x1;  /* sampler 0 (bit 0) is used */
1737ce99a11037e577e36480f3e29b2685b853f0330Brian
1744836217850114e0972900a68fd7d93e2e241819bBrian   if (key->scaleAndBias) {
1754836217850114e0972900a68fd7d93e2e241819bBrian      static const gl_state_index scale_state[STATE_LENGTH] =
1764836217850114e0972900a68fd7d93e2e241819bBrian         { STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 };
1774836217850114e0972900a68fd7d93e2e241819bBrian      static const gl_state_index bias_state[STATE_LENGTH] =
1784836217850114e0972900a68fd7d93e2e241819bBrian         { STATE_INTERNAL, STATE_PT_BIAS, 0, 0, 0 };
1797ce99a11037e577e36480f3e29b2685b853f0330Brian      GLint scale_p, bias_p;
1804836217850114e0972900a68fd7d93e2e241819bBrian
1814836217850114e0972900a68fd7d93e2e241819bBrian      scale_p = _mesa_add_state_reference(params, scale_state);
1824836217850114e0972900a68fd7d93e2e241819bBrian      bias_p = _mesa_add_state_reference(params, bias_state);
1837ce99a11037e577e36480f3e29b2685b853f0330Brian
1844b822a101680532ce6df52904af91194b78a16baBrian Paul      /* MAD colorTemp, colorTemp, scale, bias; */
1857ce99a11037e577e36480f3e29b2685b853f0330Brian      _mesa_init_instructions(inst + ic, 1);
1867ce99a11037e577e36480f3e29b2685b853f0330Brian      inst[ic].Opcode = OPCODE_MAD;
187286380020b146d600ac86d519ddfbf765a5965b2Brian      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
188286380020b146d600ac86d519ddfbf765a5965b2Brian      inst[ic].DstReg.Index = colorTemp;
189286380020b146d600ac86d519ddfbf765a5965b2Brian      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
190286380020b146d600ac86d519ddfbf765a5965b2Brian      inst[ic].SrcReg[0].Index = colorTemp;
1914836217850114e0972900a68fd7d93e2e241819bBrian      inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR;
1927ce99a11037e577e36480f3e29b2685b853f0330Brian      inst[ic].SrcReg[1].Index = scale_p;
1934836217850114e0972900a68fd7d93e2e241819bBrian      inst[ic].SrcReg[2].File = PROGRAM_STATE_VAR;
1947ce99a11037e577e36480f3e29b2685b853f0330Brian      inst[ic].SrcReg[2].Index = bias_p;
1957ce99a11037e577e36480f3e29b2685b853f0330Brian      ic++;
1967ce99a11037e577e36480f3e29b2685b853f0330Brian   }
1977ce99a11037e577e36480f3e29b2685b853f0330Brian
1984b822a101680532ce6df52904af91194b78a16baBrian Paul   if (key->pixelMaps) {
1994b822a101680532ce6df52904af91194b78a16baBrian Paul      const GLuint temp = 1;
2004b822a101680532ce6df52904af91194b78a16baBrian Paul
2014b822a101680532ce6df52904af91194b78a16baBrian Paul      /* create the colormap/texture now if not already done */
2024b822a101680532ce6df52904af91194b78a16baBrian Paul      if (!st->pixel_xfer.pixelmap_texture) {
2039adcab9cd464d659288e31e6767efb5dee3894ffBryan Cain         st->pixel_xfer.pixelmap_texture = st_create_color_map_texture(ctx);
20476c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul         st->pixel_xfer.pixelmap_sampler_view =
20576c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul            st_create_texture_sampler_view(st->pipe,
20676c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul                                           st->pixel_xfer.pixelmap_texture);
2074b822a101680532ce6df52904af91194b78a16baBrian Paul      }
2084b822a101680532ce6df52904af91194b78a16baBrian Paul
2094b822a101680532ce6df52904af91194b78a16baBrian Paul      /* with a little effort, we can do four pixel map look-ups with
2104b822a101680532ce6df52904af91194b78a16baBrian Paul       * two TEX instructions:
2114b822a101680532ce6df52904af91194b78a16baBrian Paul       */
2124b822a101680532ce6df52904af91194b78a16baBrian Paul
2134b822a101680532ce6df52904af91194b78a16baBrian Paul      /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */
2144b822a101680532ce6df52904af91194b78a16baBrian Paul      _mesa_init_instructions(inst + ic, 1);
2154b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].Opcode = OPCODE_TEX;
2164b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
2174b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].DstReg.Index = temp;
2184b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].DstReg.WriteMask = WRITEMASK_XY; /* write R,G */
2194b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
2204b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].SrcReg[0].Index = colorTemp;
2214b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].TexSrcUnit = 1;
2224b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
2234b822a101680532ce6df52904af91194b78a16baBrian Paul      ic++;
2244b822a101680532ce6df52904af91194b78a16baBrian Paul
2254b822a101680532ce6df52904af91194b78a16baBrian Paul      /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */
2264b822a101680532ce6df52904af91194b78a16baBrian Paul      _mesa_init_instructions(inst + ic, 1);
2274b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].Opcode = OPCODE_TEX;
2284b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
2294b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].DstReg.Index = temp;
2304b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].DstReg.WriteMask = WRITEMASK_ZW; /* write B,A */
2314b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
2324b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].SrcReg[0].Index = colorTemp;
2334b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W,
2344b822a101680532ce6df52904af91194b78a16baBrian Paul                                                 SWIZZLE_Z, SWIZZLE_W);
2354b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].TexSrcUnit = 1;
2364b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].TexSrcTarget = TEXTURE_2D_INDEX;
2374b822a101680532ce6df52904af91194b78a16baBrian Paul      ic++;
2384b822a101680532ce6df52904af91194b78a16baBrian Paul
2394b822a101680532ce6df52904af91194b78a16baBrian Paul      /* MOV colorTemp, temp; */
2404b822a101680532ce6df52904af91194b78a16baBrian Paul      _mesa_init_instructions(inst + ic, 1);
2414b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].Opcode = OPCODE_MOV;
2424b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].DstReg.File = PROGRAM_TEMPORARY;
2434b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].DstReg.Index = colorTemp;
2444b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
2454b822a101680532ce6df52904af91194b78a16baBrian Paul      inst[ic].SrcReg[0].Index = temp;
2464b822a101680532ce6df52904af91194b78a16baBrian Paul      ic++;
2474b822a101680532ce6df52904af91194b78a16baBrian Paul
2484b822a101680532ce6df52904af91194b78a16baBrian Paul      fp->Base.SamplersUsed |= (1 << 1);  /* sampler 1 is used */
2494b822a101680532ce6df52904af91194b78a16baBrian Paul   }
2504b822a101680532ce6df52904af91194b78a16baBrian Paul
251286380020b146d600ac86d519ddfbf765a5965b2Brian   /* Modify last instruction's dst reg to write to result.color */
252286380020b146d600ac86d519ddfbf765a5965b2Brian   {
253286380020b146d600ac86d519ddfbf765a5965b2Brian      struct prog_instruction *last = &inst[ic - 1];
254286380020b146d600ac86d519ddfbf765a5965b2Brian      last->DstReg.File = PROGRAM_OUTPUT;
2558d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul      last->DstReg.Index = FRAG_RESULT_COLOR;
256286380020b146d600ac86d519ddfbf765a5965b2Brian   }
257286380020b146d600ac86d519ddfbf765a5965b2Brian
2587ce99a11037e577e36480f3e29b2685b853f0330Brian   /* END; */
2597ce99a11037e577e36480f3e29b2685b853f0330Brian   _mesa_init_instructions(inst + ic, 1);
2607ce99a11037e577e36480f3e29b2685b853f0330Brian   inst[ic].Opcode = OPCODE_END;
2617ce99a11037e577e36480f3e29b2685b853f0330Brian   ic++;
2627ce99a11037e577e36480f3e29b2685b853f0330Brian
2637ce99a11037e577e36480f3e29b2685b853f0330Brian   assert(ic <= MAX_INST);
2647ce99a11037e577e36480f3e29b2685b853f0330Brian
2657ce99a11037e577e36480f3e29b2685b853f0330Brian
2667ce99a11037e577e36480f3e29b2685b853f0330Brian   fp->Base.Instructions = _mesa_alloc_instructions(ic);
2677ce99a11037e577e36480f3e29b2685b853f0330Brian   if (!fp->Base.Instructions) {
2687ce99a11037e577e36480f3e29b2685b853f0330Brian      _mesa_error(ctx, GL_OUT_OF_MEMORY,
2697ce99a11037e577e36480f3e29b2685b853f0330Brian                  "generating pixel transfer program");
2707b6b5f51028c72e8a868e87cad41892977552218Vinson Lee      _mesa_free_parameter_list(params);
2717ce99a11037e577e36480f3e29b2685b853f0330Brian      return NULL;
2727ce99a11037e577e36480f3e29b2685b853f0330Brian   }
2737ce99a11037e577e36480f3e29b2685b853f0330Brian
2747ce99a11037e577e36480f3e29b2685b853f0330Brian   _mesa_copy_instructions(fp->Base.Instructions, inst, ic);
2757ce99a11037e577e36480f3e29b2685b853f0330Brian   fp->Base.NumInstructions = ic;
2767ce99a11037e577e36480f3e29b2685b853f0330Brian   fp->Base.Parameters = params;
2777ce99a11037e577e36480f3e29b2685b853f0330Brian
278ab3f6015aa7227da3137b60456deb3905680f95fBrian#if 0
2797ce99a11037e577e36480f3e29b2685b853f0330Brian   printf("========= pixel transfer prog\n");
2807ce99a11037e577e36480f3e29b2685b853f0330Brian   _mesa_print_program(&fp->Base);
2817ce99a11037e577e36480f3e29b2685b853f0330Brian   _mesa_print_parameter_list(fp->Base.Parameters);
282ab3f6015aa7227da3137b60456deb3905680f95fBrian#endif
2837ce99a11037e577e36480f3e29b2685b853f0330Brian
2847ce99a11037e577e36480f3e29b2685b853f0330Brian   return fp;
2857ce99a11037e577e36480f3e29b2685b853f0330Brian}
2867ce99a11037e577e36480f3e29b2685b853f0330Brian
2877ce99a11037e577e36480f3e29b2685b853f0330Brian
2887ce99a11037e577e36480f3e29b2685b853f0330Brian
289d6a739f6b0658414a81715bf690159f7cfdb4961Brian/**
290d6a739f6b0658414a81715bf690159f7cfdb4961Brian * Update st->pixel_xfer.program in response to new pixel-transfer state.
291d6a739f6b0658414a81715bf690159f7cfdb4961Brian */
2927ce99a11037e577e36480f3e29b2685b853f0330Brianstatic void
2937ce99a11037e577e36480f3e29b2685b853f0330Brianupdate_pixel_transfer(struct st_context *st)
2947ce99a11037e577e36480f3e29b2685b853f0330Brian{
295f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg   struct gl_context *ctx = st->ctx;
2968aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   struct state_key key;
2978aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   struct gl_fragment_program *fp;
2988aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
2998aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   make_state_key(st->ctx, &key);
3008aa42546add1fef4949e2d4ceded62e2d1dd0215Brian
3018aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   fp = (struct gl_fragment_program *)
302d6a739f6b0658414a81715bf690159f7cfdb4961Brian      _mesa_search_program_cache(st->pixel_xfer.cache, &key, sizeof(key));
3038aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   if (!fp) {
3044836217850114e0972900a68fd7d93e2e241819bBrian      fp = get_pixel_transfer_program(st->ctx, &key);
305d6a739f6b0658414a81715bf690159f7cfdb4961Brian      _mesa_program_cache_insert(st->ctx, st->pixel_xfer.cache,
3068aa42546add1fef4949e2d4ceded62e2d1dd0215Brian                                 &key, sizeof(key), &fp->Base);
3078aa42546add1fef4949e2d4ceded62e2d1dd0215Brian   }
3087ce99a11037e577e36480f3e29b2685b853f0330Brian
3094b822a101680532ce6df52904af91194b78a16baBrian Paul   if (ctx->Pixel.MapColorFlag) {
3104b822a101680532ce6df52904af91194b78a16baBrian Paul      load_color_map_texture(ctx, st->pixel_xfer.pixelmap_texture);
3114b822a101680532ce6df52904af91194b78a16baBrian Paul   }
3124b822a101680532ce6df52904af91194b78a16baBrian Paul   st->pixel_xfer.pixelmap_enabled = ctx->Pixel.MapColorFlag;
3134b822a101680532ce6df52904af91194b78a16baBrian Paul
314d6a739f6b0658414a81715bf690159f7cfdb4961Brian   st->pixel_xfer.program = (struct st_fragment_program *) fp;
3157ce99a11037e577e36480f3e29b2685b853f0330Brian}
3167ce99a11037e577e36480f3e29b2685b853f0330Brian
3177ce99a11037e577e36480f3e29b2685b853f0330Brian
3187ce99a11037e577e36480f3e29b2685b853f0330Brian
3197ce99a11037e577e36480f3e29b2685b853f0330Brianconst struct st_tracked_state st_update_pixel_transfer = {
32054507125e735ffa595e252282eaabf38095c21e1Alan Hourihane   "st_update_pixel_transfer",				/* name */
32154507125e735ffa595e252282eaabf38095c21e1Alan Hourihane   {							/* dirty */
32273578ba9c4938db3a23198c3a2ddf843cfc4f700Eric Anholt      _NEW_PIXEL,					/* mesa */
32354507125e735ffa595e252282eaabf38095c21e1Alan Hourihane      0,						/* st */
3247ce99a11037e577e36480f3e29b2685b853f0330Brian   },
32554507125e735ffa595e252282eaabf38095c21e1Alan Hourihane   update_pixel_transfer				/* update */
3267ce99a11037e577e36480f3e29b2685b853f0330Brian};
327