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" 553dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul#include "tgsi/tgsi_scan.h" 567dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 577dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** Approx number of new tokens for instructions in pstip_transform_inst() */ 587dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#define NUM_NEW_TOKENS 50 597dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 607dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 617dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic void 627dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_update_stipple_texture(struct pipe_context *pipe, 637dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_resource *tex, 647dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul const uint32_t pattern[32]) 657dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 667dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul static const uint bit31 = 1 << 31; 677dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_transfer *transfer; 687dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ubyte *data; 697dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int i, j; 707dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 717dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* map texture memory */ 727dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transfer = pipe_get_transfer(pipe, tex, 0, 0, 737dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul PIPE_TRANSFER_WRITE, 0, 0, 32, 32); 747dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul data = pipe->transfer_map(pipe, transfer); 757dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 767dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* 777dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Load alpha texture. 787dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Note: 0 means keep the fragment, 255 means kill it. 797dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * We'll negate the texel value and use KILP which kills if value 807dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * is negative. 817dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 827dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul for (i = 0; i < 32; i++) { 837dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul for (j = 0; j < 32; j++) { 847dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pattern[i] & (bit31 >> j)) { 857dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* fragment "on" */ 867dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul data[i * transfer->stride + j] = 0; 877dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 887dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else { 897dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* fragment "off" */ 907dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul data[i * transfer->stride + j] = 255; 917dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 927dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 937dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 947dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 957dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* unmap */ 967dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pipe->transfer_unmap(pipe, transfer); 977dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pipe->transfer_destroy(pipe, transfer); 987dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 997dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1007dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1017dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1027dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Create a 32x32 alpha8 texture that encodes the given stipple pattern. 1037dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1047dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstruct pipe_resource * 1057dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_create_stipple_texture(struct pipe_context *pipe, 1067dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul const uint32_t pattern[32]) 1077dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 1087dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_screen *screen = pipe->screen; 1097dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_resource templat, *tex; 1107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul memset(&templat, 0, sizeof(templat)); 1127dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.target = PIPE_TEXTURE_2D; 1137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.format = PIPE_FORMAT_A8_UNORM; 1147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.last_level = 0; 1157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.width0 = 32; 1167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.height0 = 32; 1177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.depth0 = 1; 1187dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.array_size = 1; 1197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.bind = PIPE_BIND_SAMPLER_VIEW; 1207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul tex = screen->resource_create(screen, &templat); 1227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (tex) 1247dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul util_pstipple_update_stipple_texture(pipe, tex, pattern); 1257dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return tex; 1277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 1287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1317dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Create sampler view to sample the stipple texture. 1327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstruct pipe_sampler_view * 1347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_create_sampler_view(struct pipe_context *pipe, 1357dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_resource *tex) 1367dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 1377dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_sampler_view templat, *sv; 1387dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1397dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul u_sampler_view_default_template(&templat, tex, tex->format); 1407dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul sv = pipe->create_sampler_view(pipe, tex, &templat); 1417dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1427dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return sv; 1437dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 1447dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1457dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1467dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1477dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Create the sampler CSO that'll be used for stippling. 1487dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1497dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulvoid * 1507dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_create_sampler(struct pipe_context *pipe) 1517dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 1527dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_sampler_state templat; 1537dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul void *s; 1547dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1557dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul memset(&templat, 0, sizeof(templat)); 1567dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.wrap_s = PIPE_TEX_WRAP_REPEAT; 1577dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.wrap_t = PIPE_TEX_WRAP_REPEAT; 1587dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.wrap_r = PIPE_TEX_WRAP_REPEAT; 1597dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 1607dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.min_img_filter = PIPE_TEX_FILTER_NEAREST; 1617dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 1627dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.normalized_coords = 1; 1637dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.min_lod = 0.0f; 1647dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul templat.max_lod = 0.0f; 1657dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1667dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul s = pipe->create_sampler_state(pipe, &templat); 1677dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return s; 1687dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 1697dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1707dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1717dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1727dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1737dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Subclass of tgsi_transform_context, used for transforming the 1747dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * user's fragment shader to add the extra texture sample and fragment kill 1757dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * instructions. 1767dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1777dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstruct pstip_transform_context { 1787dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_transform_context base; 1793dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul struct tgsi_shader_info info; 1807dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint tempsUsed; /**< bitmask */ 1817dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int wincoordInput; 1827dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int maxInput; 1837dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint samplersUsed; /**< bitfield of samplers used */ 1847dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int freeSampler; /** an available sampler for the pstipple */ 1857dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int texTemp; /**< temp registers */ 1867dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int numImmed; 1877dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul boolean firstInstruction; 1883dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul uint coordOrigin; 1897dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul}; 1907dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1917dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 1927dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 1937dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * TGSI declaration transform callback. 1943dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * Track samplers used, temps used, inputs used. 1957dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 1967dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic void 1977dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulpstip_transform_decl(struct tgsi_transform_context *ctx, 1987dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_declaration *decl) 1997dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 2007dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pstip_transform_context *pctx = 2017dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul (struct pstip_transform_context *) ctx; 2027dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2033dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul /* XXX we can use tgsi_shader_info instead of some of this */ 2043dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul 2057dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (decl->Declaration.File == TGSI_FILE_SAMPLER) { 2067dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint i; 2073dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul for (i = decl->Range.First; i <= decl->Range.Last; i++) { 2087dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->samplersUsed |= 1 << i; 2097dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else if (decl->Declaration.File == TGSI_FILE_INPUT) { 2127dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->maxInput = MAX2(pctx->maxInput, (int) decl->Range.Last); 2137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) 2147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->wincoordInput = (int) decl->Range.First; 2157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { 2177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint i; 2183dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul for (i = decl->Range.First; i <= decl->Range.Last; i++) { 2197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->tempsUsed |= (1 << i); 2207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_declaration(ctx, decl); 2247dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 2257dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic void 2287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulpstip_transform_immed(struct tgsi_transform_context *ctx, 2297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_immediate *immed) 2307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 2317dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pstip_transform_context *pctx = 2327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul (struct pstip_transform_context *) ctx; 2337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->numImmed++; 2347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 2357dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2367dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2377dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 2387dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. 2397dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 2407dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic int 2417dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulfree_bit(uint bitfield) 2427dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 2437dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return ffs(~bitfield) - 1; 2447dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 2457dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2467dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2477dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 2487dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * TGSI instruction transform callback. 2493dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * Before the first instruction, insert our new code to sample the 2503dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * stipple texture (using the fragment coord register) then kill the 2513dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * fragment if the stipple texture bit is off. 2523dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * 2533dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * Insert: 2543dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * declare new registers 2553dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * MUL texTemp, INPUT[wincoord], 1/32; 2563dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * TEX texTemp, texTemp, sampler; 2573dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * KIL -texTemp; # if -texTemp < 0, KILL fragment 2583dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul * [...original code...] 2597dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 2607dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstatic void 2617dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulpstip_transform_inst(struct tgsi_transform_context *ctx, 2627dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_instruction *inst) 2637dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 2647dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pstip_transform_context *pctx = 2657dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul (struct pstip_transform_context *) ctx; 2667dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2677dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->firstInstruction) { 2687dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* emit our new declarations before the first instruction */ 2697dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2707dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_declaration decl; 2717dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_instruction newInst; 2727dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint i; 2737dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul int wincoordInput; 2747dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2753dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul /* find free texture sampler */ 2767dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->freeSampler = free_bit(pctx->samplersUsed); 2777dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) 2787dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; 2797dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2807dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->wincoordInput < 0) 2817dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul wincoordInput = pctx->maxInput + 1; 2827dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else 2837dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul wincoordInput = pctx->wincoordInput; 2847dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2853dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul /* find one free temp register */ 2867dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul for (i = 0; i < 32; i++) { 2877dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if ((pctx->tempsUsed & (1 << i)) == 0) { 2887dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* found a free temp */ 2897dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->texTemp < 0) 2907dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->texTemp = i; 2917dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul else 2927dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul break; 2937dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2947dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 2957dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul assert(pctx->texTemp >= 0); 2967dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 2977dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (pctx->wincoordInput < 0) { 2987dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* declare new position input reg */ 2997dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl = tgsi_default_full_declaration(); 3007dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.File = TGSI_FILE_INPUT; 3011279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez decl.Declaration.Interpolate = 1; 3027dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.Semantic = 1; 3037dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Semantic.Name = TGSI_SEMANTIC_POSITION; 3047dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Semantic.Index = 0; 3057dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.First = 3067dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.Last = wincoordInput; 3071279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; 3087dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_declaration(ctx, &decl); 3097dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 3107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* declare new sampler */ 3127dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl = tgsi_default_full_declaration(); 3137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.File = TGSI_FILE_SAMPLER; 3147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.First = 3157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.Last = pctx->freeSampler; 3167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_declaration(ctx, &decl); 3177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3187dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* declare new temp regs */ 3197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl = tgsi_default_full_declaration(); 3207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Declaration.File = TGSI_FILE_TEMPORARY; 3217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.First = 3227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul decl.Range.Last = pctx->texTemp; 3237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_declaration(ctx, &decl); 3247dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3257dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* emit immediate = {1/32, 1/32, 1, 1} 3267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * The index/position of this immediate will be pctx->numImmed 3277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 3287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul { 3297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; 3307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct tgsi_full_immediate immed; 3317dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul uint size = 4; 3327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed = tgsi_default_full_immediate(); 3337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.Immediate.NrTokens = 1 + size; /* one for the token itself */ 3347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.u[0].Float = value[0]; 3357dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.u[1].Float = value[1]; 3367dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.u[2].Float = value[2]; 3377dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul immed.u[3].Float = value[3]; 3387dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_immediate(ctx, &immed); 3397dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 3407dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3417dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul pctx->firstInstruction = FALSE; 3427dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3437dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3447dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* 3457dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Insert new MUL/TEX/KILP instructions at start of program 3467dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Take gl_FragCoord, divide by 32 (stipple size), sample the 3477dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * texture and kill fragment if needed. 3487dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * 3497dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * We'd like to use non-normalized texcoords to index into a RECT 3507dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * texture, but we can only use REPEAT wrap mode with normalized 3517dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * texcoords. Darn. 3527dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 3537dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3547dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* XXX invert wincoord if origin isn't lower-left... */ 3557dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3567dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* MUL texTemp, INPUT[wincoord], 1/32; */ 3577dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst = tgsi_default_full_instruction(); 3587dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.Opcode = TGSI_OPCODE_MUL; 3597dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumDstRegs = 1; 3607dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; 3617dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Dst[0].Register.Index = pctx->texTemp; 3627dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumSrcRegs = 2; 3637dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.File = TGSI_FILE_INPUT; 3647dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.Index = wincoordInput; 3657dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE; 3667dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[1].Register.Index = pctx->numImmed; 3677dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_instruction(ctx, &newInst); 3687dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3697dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* TEX texTemp, texTemp, sampler; */ 3707dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst = tgsi_default_full_instruction(); 3717dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.Opcode = TGSI_OPCODE_TEX; 3727dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumDstRegs = 1; 3737dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; 3747dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Dst[0].Register.Index = pctx->texTemp; 3757dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumSrcRegs = 2; 3767dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.Texture = TRUE; 3777dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Texture.Texture = TGSI_TEXTURE_2D; 3787dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 3797dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.Index = pctx->texTemp; 3807dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[1].Register.File = TGSI_FILE_SAMPLER; 3817dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[1].Register.Index = pctx->freeSampler; 3827dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_instruction(ctx, &newInst); 3837dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3847dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* KIL -texTemp; # if -texTemp < 0, KILL fragment */ 3857dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst = tgsi_default_full_instruction(); 3867dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.Opcode = TGSI_OPCODE_KIL; 3877dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumDstRegs = 0; 3887dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Instruction.NumSrcRegs = 1; 3897dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 3907dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.Index = pctx->texTemp; 3917dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newInst.Src[0].Register.Negate = 1; 3927dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_instruction(ctx, &newInst); 3937dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 3947dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3957dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul /* emit this instruction */ 3967dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul ctx->emit_instruction(ctx, inst); 3977dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 3987dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 3997dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4007dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul/** 4017dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * Given a fragment shader, return a new fragment shader which 4027dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul * samples a stipple texture and executes KILL. 4037dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul */ 4047dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulstruct pipe_shader_state * 4057dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paulutil_pstipple_create_fragment_shader(struct pipe_context *pipe, 4067dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_shader_state *fs, 4077dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul unsigned *samplerUnitOut) 4087dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul{ 4097dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pipe_shader_state *new_fs; 4107dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul struct pstip_transform_context transform; 4117dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul const uint newLen = tgsi_num_tokens(fs->tokens) + NUM_NEW_TOKENS; 4123dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul unsigned i; 4137dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4147dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul new_fs = MALLOC(sizeof(*new_fs)); 4157dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (!new_fs) 4167dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return NULL; 4177dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4187dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul new_fs->tokens = tgsi_alloc_tokens(newLen); 4197dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul if (!new_fs->tokens) { 4207dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul FREE(new_fs); 4217dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return NULL; 4227dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul } 4237dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4243dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul /* Setup shader transformation info/context. 4253dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul */ 4267dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul memset(&transform, 0, sizeof(transform)); 4277dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.wincoordInput = -1; 4287dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.maxInput = -1; 4297dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.texTemp = -1; 4307dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.firstInstruction = TRUE; 4313dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul transform.coordOrigin = TGSI_FS_COORD_ORIGIN_UPPER_LEFT; 4327dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.base.transform_instruction = pstip_transform_inst; 4337dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.base.transform_declaration = pstip_transform_decl; 4347dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul transform.base.transform_immediate = pstip_transform_immed; 4357dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4363dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul tgsi_scan_shader(fs->tokens, &transform.info); 4373dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul 4383dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul /* find fragment coordinate origin property */ 4393dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul for (i = 0; i < transform.info.num_properties; i++) { 4403dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul if (transform.info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN) 4413dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul transform.coordOrigin = transform.info.properties[i].data[0]; 4423dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul } 4433dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul 4447dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul tgsi_transform_shader(fs->tokens, 4457dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul (struct tgsi_token *) new_fs->tokens, 4467dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul newLen, &transform.base); 4477dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4487dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#if 0 /* DEBUG */ 4497dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul tgsi_dump(fs->tokens, 0); 4503dde6be908d827f4d6d54e0968ae83c2c4dfa87cBrian Paul tgsi_dump(new_fs->tokens, 0); 4517dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul#endif 4527dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4537dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul assert(transform.freeSampler < PIPE_MAX_SAMPLERS); 4547dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul *samplerUnitOut = transform.freeSampler; 4557dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 4567dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul return new_fs; 4577dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul} 4587dcf019af2e76a4c6e0391c3c5e1d50966367df8Brian Paul 459