u_pstipple.c revision 7dcf019af2e76a4c6e0391c3c5e1d50966367df8
17dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/************************************************************************** 27dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 37dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 47dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Copyright 2010 VMware, Inc. 57dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * All Rights Reserved. 67dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 77dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 87dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * copy of this software and associated documentation files (the 97dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * "Software"), to deal in the Software without restriction, including 107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * without limitation the rights to use, copy, modify, merge, publish, 117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * distribute, sub license, and/or sell copies of the Software, and to 127dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * permit persons to whom the Software is furnished to do so, subject to 137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * the following conditions: 147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * The above copyright notice and this permission notice (including the 167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * next paragraph) shall be included in all copies or substantial portions 177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * of the Software. 187dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 247dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 257dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul **************************************************************************/ 287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Polygon stipple helper module. Drivers/GPUs which don't support polygon 317dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * stipple natively can use this module to simulate it. 327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Basically, modify fragment shader to sample the 32x32 stipple pattern 347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * texture and do a fragment kill for the 'off' bits. 357dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 367dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * This was originally a 'draw' module stage, but since we don't need 377dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * vertex window coords or anything, it can be a stand-alone utility module. 387dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 397dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Authors: Brian Paul 407dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 417dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 427dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 437dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "pipe/p_context.h" 447dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "pipe/p_defines.h" 457dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "pipe/p_shader_tokens.h" 467dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "util/u_inlines.h" 477dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 487dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "util/u_format.h" 497dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "util/u_memory.h" 507dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "util/u_pstipple.h" 517dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "util/u_sampler.h" 527dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 537dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "tgsi/tgsi_transform.h" 547dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#include "tgsi/tgsi_dump.h" 557dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 567dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** Approx number of new tokens for instructions in pstip_transform_inst() */ 577dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#define NUM_NEW_TOKENS 50 587dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 597dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 607dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic void 617dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_update_stipple_texture(struct pipe_context *pipe, 627dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_resource *tex, 637dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul const uint32_t pattern[32]) 647dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 657dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul static const uint bit31 = 1 << 31; 667dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_transfer *transfer; 677dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ubyte *data; 687dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int i, j; 697dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 707dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* map texture memory */ 717dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transfer = pipe_get_transfer(pipe, tex, 0, 0, 727dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul PIPE_TRANSFER_WRITE, 0, 0, 32, 32); 737dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul data = pipe->transfer_map(pipe, transfer); 747dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 757dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* 767dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Load alpha texture. 777dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Note: 0 means keep the fragment, 255 means kill it. 787dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * We'll negate the texel value and use KILP which kills if value 797dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * is negative. 807dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 817dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul for (i = 0; i < 32; i++) { 827dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul for (j = 0; j < 32; j++) { 837dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pattern[i] & (bit31 >> j)) { 847dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* fragment "on" */ 857dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul data[i * transfer->stride + j] = 0; 867dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 877dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else { 887dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* fragment "off" */ 897dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul data[i * transfer->stride + j] = 255; 907dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 917dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 927dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 937dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 947dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* unmap */ 957dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pipe->transfer_unmap(pipe, transfer); 967dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pipe->transfer_destroy(pipe, transfer); 977dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 987dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 997dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1007dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1017dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Create a 32x32 alpha8 texture that encodes the given stipple pattern. 1027dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1037dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstruct pipe_resource * 1047dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_create_stipple_texture(struct pipe_context *pipe, 1057dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul const uint32_t pattern[32]) 1067dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 1077dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_screen *screen = pipe->screen; 1087dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_resource templat, *tex; 1097dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul memset(&templat, 0, sizeof(templat)); 1117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.target = PIPE_TEXTURE_2D; 1127dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.format = PIPE_FORMAT_A8_UNORM; 1137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.last_level = 0; 1147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.width0 = 32; 1157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.height0 = 32; 1167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.depth0 = 1; 1177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.array_size = 1; 1187dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.bind = PIPE_BIND_SAMPLER_VIEW; 1197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul tex = screen->resource_create(screen, &templat); 1217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (tex) 1237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul util_pstipple_update_stipple_texture(pipe, tex, pattern); 1247dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1257dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return tex; 1267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 1277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Create sampler view to sample the stipple texture. 1317dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstruct pipe_sampler_view * 1337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_create_sampler_view(struct pipe_context *pipe, 1347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_resource *tex) 1357dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 1367dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_sampler_view templat, *sv; 1377dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1387dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul u_sampler_view_default_template(&templat, tex, tex->format); 1397dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul sv = pipe->create_sampler_view(pipe, tex, &templat); 1407dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1417dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return sv; 1427dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 1437dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1447dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1457dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1467dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Create the sampler CSO that'll be used for stippling. 1477dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1487dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulvoid * 1497dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_create_sampler(struct pipe_context *pipe) 1507dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 1517dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_sampler_state templat; 1527dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul void *s; 1537dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1547dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul memset(&templat, 0, sizeof(templat)); 1557dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.wrap_s = PIPE_TEX_WRAP_REPEAT; 1567dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.wrap_t = PIPE_TEX_WRAP_REPEAT; 1577dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.wrap_r = PIPE_TEX_WRAP_REPEAT; 1587dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 1597dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.min_img_filter = PIPE_TEX_FILTER_NEAREST; 1607dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 1617dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.normalized_coords = 1; 1627dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.min_lod = 0.0f; 1637dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.max_lod = 0.0f; 1647dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1657dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul s = pipe->create_sampler_state(pipe, &templat); 1667dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return s; 1677dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 1687dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1697dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1707dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1717dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1727dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Subclass of tgsi_transform_context, used for transforming the 1737dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * user's fragment shader to add the extra texture sample and fragment kill 1747dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * instructions. 1757dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1767dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstruct pstip_transform_context { 1777dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_transform_context base; 1787dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint tempsUsed; /**< bitmask */ 1797dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int wincoordInput; 1807dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int maxInput; 1817dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint samplersUsed; /**< bitfield of samplers used */ 1827dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int freeSampler; /** an available sampler for the pstipple */ 1837dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int texTemp; /**< temp registers */ 1847dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int numImmed; 1857dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul boolean firstInstruction; 1867dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul}; 1877dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1887dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1897dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1907dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * TGSI declaration transform callback. 1917dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Look for a free sampler, a free input attrib, and two free temp regs. 1927dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1937dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic void 1947dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulpstip_transform_decl(struct tgsi_transform_context *ctx, 1957dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_declaration *decl) 1967dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 1977dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pstip_transform_context *pctx = 1987dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul (struct pstip_transform_context *) ctx; 1997dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2007dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (decl->Declaration.File == TGSI_FILE_SAMPLER) { 2017dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint i; 2027dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul for (i = decl->Range.First; 2037dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul i <= decl->Range.Last; i++) { 2047dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->samplersUsed |= 1 << i; 2057dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2067dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2077dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else if (decl->Declaration.File == TGSI_FILE_INPUT) { 2087dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->maxInput = MAX2(pctx->maxInput, (int) decl->Range.Last); 2097dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) 2107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->wincoordInput = (int) decl->Range.First; 2117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2127dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { 2137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint i; 2147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul for (i = decl->Range.First; 2157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul i <= decl->Range.Last; i++) { 2167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->tempsUsed |= (1 << i); 2177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2187dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_declaration(ctx, decl); 2217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 2227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2247dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic void 2257dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulpstip_transform_immed(struct tgsi_transform_context *ctx, 2267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_immediate *immed) 2277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 2287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pstip_transform_context *pctx = 2297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul (struct pstip_transform_context *) ctx; 2307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->numImmed++; 2317dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 2327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 2357dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. 2367dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 2377dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic int 2387dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulfree_bit(uint bitfield) 2397dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 2407dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return ffs(~bitfield) - 1; 2417dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 2427dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2437dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2447dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 2457dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * TGSI instruction transform callback. 2467dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Replace writes to result.color w/ a temp reg. 2477dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Upon END instruction, insert texture sampling code for antialiasing. 2487dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 2497dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic void 2507dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulpstip_transform_inst(struct tgsi_transform_context *ctx, 2517dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_instruction *inst) 2527dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 2537dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pstip_transform_context *pctx = 2547dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul (struct pstip_transform_context *) ctx; 2557dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2567dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->firstInstruction) { 2577dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* emit our new declarations before the first instruction */ 2587dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2597dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_declaration decl; 2607dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_instruction newInst; 2617dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint i; 2627dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int wincoordInput; 2637dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2647dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* find free sampler */ 2657dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->freeSampler = free_bit(pctx->samplersUsed); 2667dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) 2677dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; 2687dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2697dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->wincoordInput < 0) 2707dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul wincoordInput = pctx->maxInput + 1; 2717dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else 2727dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul wincoordInput = pctx->wincoordInput; 2737dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2747dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* find one free temp reg */ 2757dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul for (i = 0; i < 32; i++) { 2767dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if ((pctx->tempsUsed & (1 << i)) == 0) { 2777dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* found a free temp */ 2787dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->texTemp < 0) 2797dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->texTemp = i; 2807dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else 2817dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul break; 2827dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2837dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2847dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul assert(pctx->texTemp >= 0); 2857dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2867dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->wincoordInput < 0) { 2877dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* declare new position input reg */ 2887dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl = tgsi_default_full_declaration(); 2897dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.File = TGSI_FILE_INPUT; 2907dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; 2917dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.Semantic = 1; 2927dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Semantic.Name = TGSI_SEMANTIC_POSITION; 2937dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Semantic.Index = 0; 2947dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.First = 2957dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.Last = wincoordInput; 2967dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_declaration(ctx, &decl); 2977dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2987dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2997dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* declare new sampler */ 3007dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl = tgsi_default_full_declaration(); 3017dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.File = TGSI_FILE_SAMPLER; 3027dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.First = 3037dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.Last = pctx->freeSampler; 3047dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_declaration(ctx, &decl); 3057dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3067dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* declare new temp regs */ 3077dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl = tgsi_default_full_declaration(); 3087dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.File = TGSI_FILE_TEMPORARY; 3097dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.First = 3107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.Last = pctx->texTemp; 3117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_declaration(ctx, &decl); 3127dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* emit immediate = {1/32, 1/32, 1, 1} 3147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * The index/position of this immediate will be pctx->numImmed 3157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 3167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul { 3177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; 3187dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_immediate immed; 3197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint size = 4; 3207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed = tgsi_default_full_immediate(); 3217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.Immediate.NrTokens = 1 + size; /* one for the token itself */ 3227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.u[0].Float = value[0]; 3237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.u[1].Float = value[1]; 3247dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.u[2].Float = value[2]; 3257dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.u[3].Float = value[3]; 3267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_immediate(ctx, &immed); 3277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 3287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->firstInstruction = FALSE; 3307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3317dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* 3337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Insert new MUL/TEX/KILP instructions at start of program 3347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Take gl_FragCoord, divide by 32 (stipple size), sample the 3357dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * texture and kill fragment if needed. 3367dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 3377dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * We'd like to use non-normalized texcoords to index into a RECT 3387dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * texture, but we can only use REPEAT wrap mode with normalized 3397dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * texcoords. Darn. 3407dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 3417dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3427dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* XXX invert wincoord if origin isn't lower-left... */ 3437dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3447dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* MUL texTemp, INPUT[wincoord], 1/32; */ 3457dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst = tgsi_default_full_instruction(); 3467dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.Opcode = TGSI_OPCODE_MUL; 3477dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumDstRegs = 1; 3487dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; 3497dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Dst[0].Register.Index = pctx->texTemp; 3507dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumSrcRegs = 2; 3517dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.File = TGSI_FILE_INPUT; 3527dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.Index = wincoordInput; 3537dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE; 3547dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[1].Register.Index = pctx->numImmed; 3557dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_instruction(ctx, &newInst); 3567dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3577dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* TEX texTemp, texTemp, sampler; */ 3587dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst = tgsi_default_full_instruction(); 3597dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.Opcode = TGSI_OPCODE_TEX; 3607dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumDstRegs = 1; 3617dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; 3627dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Dst[0].Register.Index = pctx->texTemp; 3637dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumSrcRegs = 2; 3647dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.Texture = TRUE; 3657dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Texture.Texture = TGSI_TEXTURE_2D; 3667dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 3677dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.Index = pctx->texTemp; 3687dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[1].Register.File = TGSI_FILE_SAMPLER; 3697dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[1].Register.Index = pctx->freeSampler; 3707dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_instruction(ctx, &newInst); 3717dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3727dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* KIL -texTemp; # if -texTemp < 0, KILL fragment */ 3737dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst = tgsi_default_full_instruction(); 3747dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.Opcode = TGSI_OPCODE_KIL; 3757dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumDstRegs = 0; 3767dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumSrcRegs = 1; 3777dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 3787dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.Index = pctx->texTemp; 3797dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.Negate = 1; 3807dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_instruction(ctx, &newInst); 3817dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 3827dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3837dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* emit this instruction */ 3847dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_instruction(ctx, inst); 3857dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 3867dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3877dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3887dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 3897dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Given a fragment shader, return a new fragment shader which 3907dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * samples a stipple texture and executes KILL. 3917dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 3927dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstruct pipe_shader_state * 3937dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_create_fragment_shader(struct pipe_context *pipe, 3947dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_shader_state *fs, 3957dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul unsigned *samplerUnitOut) 3967dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 3977dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_shader_state *new_fs; 3987dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pstip_transform_context transform; 3997dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul const uint newLen = tgsi_num_tokens(fs->tokens) + NUM_NEW_TOKENS; 4007dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4017dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul new_fs = MALLOC(sizeof(*new_fs)); 4027dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (!new_fs) 4037dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return NULL; 4047dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4057dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul new_fs->tokens = tgsi_alloc_tokens(newLen); 4067dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (!new_fs->tokens) { 4077dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul FREE(new_fs); 4087dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return NULL; 4097dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 4107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul memset(&transform, 0, sizeof(transform)); 4127dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.wincoordInput = -1; 4137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.maxInput = -1; 4147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.texTemp = -1; 4157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.firstInstruction = TRUE; 4167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.base.transform_instruction = pstip_transform_inst; 4177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.base.transform_declaration = pstip_transform_decl; 4187dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.base.transform_immediate = pstip_transform_immed; 4197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul tgsi_transform_shader(fs->tokens, 4217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul (struct tgsi_token *) new_fs->tokens, 4227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newLen, &transform.base); 4237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4247dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#if 0 /* DEBUG */ 4257dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul tgsi_dump(fs->tokens, 0); 4267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul tgsi_dump(pstip_fs.tokens, 0); 4277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#endif 4287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul assert(transform.freeSampler < PIPE_MAX_SAMPLERS); 4307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul *samplerUnitOut = transform.freeSampler; 4317dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return new_fs; 4337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 4347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 435