Path: blob/21.2-virgl/src/gallium/auxiliary/tgsi/tgsi_ureg.c
4565 views
/**************************************************************************1*2* Copyright 2009-2010 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/262728#include "pipe/p_screen.h"29#include "pipe/p_context.h"30#include "pipe/p_state.h"31#include "tgsi/tgsi_ureg.h"32#include "tgsi/tgsi_build.h"33#include "tgsi/tgsi_from_mesa.h"34#include "tgsi/tgsi_info.h"35#include "tgsi/tgsi_dump.h"36#include "tgsi/tgsi_sanity.h"37#include "util/u_debug.h"38#include "util/u_inlines.h"39#include "util/u_memory.h"40#include "util/u_math.h"41#include "util/u_bitmask.h"42#include "GL/gl.h"43#include "compiler/shader_info.h"4445union tgsi_any_token {46struct tgsi_header header;47struct tgsi_processor processor;48struct tgsi_token token;49struct tgsi_property prop;50struct tgsi_property_data prop_data;51struct tgsi_declaration decl;52struct tgsi_declaration_range decl_range;53struct tgsi_declaration_dimension decl_dim;54struct tgsi_declaration_interp decl_interp;55struct tgsi_declaration_image decl_image;56struct tgsi_declaration_semantic decl_semantic;57struct tgsi_declaration_sampler_view decl_sampler_view;58struct tgsi_declaration_array array;59struct tgsi_immediate imm;60union tgsi_immediate_data imm_data;61struct tgsi_instruction insn;62struct tgsi_instruction_label insn_label;63struct tgsi_instruction_texture insn_texture;64struct tgsi_instruction_memory insn_memory;65struct tgsi_texture_offset insn_texture_offset;66struct tgsi_src_register src;67struct tgsi_ind_register ind;68struct tgsi_dimension dim;69struct tgsi_dst_register dst;70unsigned value;71};727374struct ureg_tokens {75union tgsi_any_token *tokens;76unsigned size;77unsigned order;78unsigned count;79};8081#define UREG_MAX_INPUT (4 * PIPE_MAX_SHADER_INPUTS)82#define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS83#define UREG_MAX_OUTPUT (4 * PIPE_MAX_SHADER_OUTPUTS)84#define UREG_MAX_CONSTANT_RANGE 3285#define UREG_MAX_HW_ATOMIC_RANGE 3286#define UREG_MAX_IMMEDIATE 409687#define UREG_MAX_ADDR 388#define UREG_MAX_ARRAY_TEMPS 2568990struct const_decl {91struct {92unsigned first;93unsigned last;94} constant_range[UREG_MAX_CONSTANT_RANGE];95unsigned nr_constant_ranges;96};9798struct hw_atomic_decl {99struct {100unsigned first;101unsigned last;102unsigned array_id;103} hw_atomic_range[UREG_MAX_HW_ATOMIC_RANGE];104unsigned nr_hw_atomic_ranges;105};106107#define DOMAIN_DECL 0108#define DOMAIN_INSN 1109110struct ureg_program111{112enum pipe_shader_type processor;113bool supports_any_inout_decl_range;114int next_shader_processor;115116struct {117enum tgsi_semantic semantic_name;118unsigned semantic_index;119enum tgsi_interpolate_mode interp;120unsigned char cylindrical_wrap;121unsigned char usage_mask;122enum tgsi_interpolate_loc interp_location;123unsigned first;124unsigned last;125unsigned array_id;126} input[UREG_MAX_INPUT];127unsigned nr_inputs, nr_input_regs;128129unsigned vs_inputs[PIPE_MAX_ATTRIBS/32];130131struct {132enum tgsi_semantic semantic_name;133unsigned semantic_index;134} system_value[UREG_MAX_SYSTEM_VALUE];135unsigned nr_system_values;136137struct {138enum tgsi_semantic semantic_name;139unsigned semantic_index;140unsigned streams;141unsigned usage_mask; /* = TGSI_WRITEMASK_* */142unsigned first;143unsigned last;144unsigned array_id;145boolean invariant;146} output[UREG_MAX_OUTPUT];147unsigned nr_outputs, nr_output_regs;148149struct {150union {151float f[4];152unsigned u[4];153int i[4];154} value;155unsigned nr;156unsigned type;157} immediate[UREG_MAX_IMMEDIATE];158unsigned nr_immediates;159160struct ureg_src sampler[PIPE_MAX_SAMPLERS];161unsigned nr_samplers;162163struct {164unsigned index;165enum tgsi_texture_type target;166enum tgsi_return_type return_type_x;167enum tgsi_return_type return_type_y;168enum tgsi_return_type return_type_z;169enum tgsi_return_type return_type_w;170} sampler_view[PIPE_MAX_SHADER_SAMPLER_VIEWS];171unsigned nr_sampler_views;172173struct {174unsigned index;175enum tgsi_texture_type target;176enum pipe_format format;177boolean wr;178boolean raw;179} image[PIPE_MAX_SHADER_IMAGES];180unsigned nr_images;181182struct {183unsigned index;184bool atomic;185} buffer[PIPE_MAX_SHADER_BUFFERS];186unsigned nr_buffers;187188struct util_bitmask *free_temps;189struct util_bitmask *local_temps;190struct util_bitmask *decl_temps;191unsigned nr_temps;192193unsigned array_temps[UREG_MAX_ARRAY_TEMPS];194unsigned nr_array_temps;195196struct const_decl const_decls[PIPE_MAX_CONSTANT_BUFFERS];197198struct hw_atomic_decl hw_atomic_decls[PIPE_MAX_HW_ATOMIC_BUFFERS];199200unsigned properties[TGSI_PROPERTY_COUNT];201202unsigned nr_addrs;203unsigned nr_instructions;204205struct ureg_tokens domain[2];206207bool use_memory[TGSI_MEMORY_TYPE_COUNT];208};209210static union tgsi_any_token error_tokens[32];211212static void tokens_error( struct ureg_tokens *tokens )213{214if (tokens->tokens && tokens->tokens != error_tokens)215FREE(tokens->tokens);216217tokens->tokens = error_tokens;218tokens->size = ARRAY_SIZE(error_tokens);219tokens->count = 0;220}221222223static void tokens_expand( struct ureg_tokens *tokens,224unsigned count )225{226unsigned old_size = tokens->size * sizeof(unsigned);227228if (tokens->tokens == error_tokens) {229return;230}231232while (tokens->count + count > tokens->size) {233tokens->size = (1 << ++tokens->order);234}235236tokens->tokens = REALLOC(tokens->tokens,237old_size,238tokens->size * sizeof(unsigned));239if (tokens->tokens == NULL) {240tokens_error(tokens);241}242}243244static void set_bad( struct ureg_program *ureg )245{246tokens_error(&ureg->domain[0]);247}248249250251static union tgsi_any_token *get_tokens( struct ureg_program *ureg,252unsigned domain,253unsigned count )254{255struct ureg_tokens *tokens = &ureg->domain[domain];256union tgsi_any_token *result;257258if (tokens->count + count > tokens->size)259tokens_expand(tokens, count);260261result = &tokens->tokens[tokens->count];262tokens->count += count;263return result;264}265266267static union tgsi_any_token *retrieve_token( struct ureg_program *ureg,268unsigned domain,269unsigned nr )270{271if (ureg->domain[domain].tokens == error_tokens)272return &error_tokens[0];273274return &ureg->domain[domain].tokens[nr];275}276277278void279ureg_property(struct ureg_program *ureg, unsigned name, unsigned value)280{281assert(name < ARRAY_SIZE(ureg->properties));282ureg->properties[name] = value;283}284285struct ureg_src286ureg_DECL_fs_input_cyl_centroid_layout(struct ureg_program *ureg,287enum tgsi_semantic semantic_name,288unsigned semantic_index,289enum tgsi_interpolate_mode interp_mode,290unsigned cylindrical_wrap,291enum tgsi_interpolate_loc interp_location,292unsigned index,293unsigned usage_mask,294unsigned array_id,295unsigned array_size)296{297unsigned i;298299assert(usage_mask != 0);300assert(usage_mask <= TGSI_WRITEMASK_XYZW);301302for (i = 0; i < ureg->nr_inputs; i++) {303if (ureg->input[i].semantic_name == semantic_name &&304ureg->input[i].semantic_index == semantic_index) {305assert(ureg->input[i].interp == interp_mode);306assert(ureg->input[i].cylindrical_wrap == cylindrical_wrap);307assert(ureg->input[i].interp_location == interp_location);308if (ureg->input[i].array_id == array_id) {309ureg->input[i].usage_mask |= usage_mask;310goto out;311}312assert((ureg->input[i].usage_mask & usage_mask) == 0);313}314}315316if (ureg->nr_inputs < UREG_MAX_INPUT) {317assert(array_size >= 1);318ureg->input[i].semantic_name = semantic_name;319ureg->input[i].semantic_index = semantic_index;320ureg->input[i].interp = interp_mode;321ureg->input[i].cylindrical_wrap = cylindrical_wrap;322ureg->input[i].interp_location = interp_location;323ureg->input[i].first = index;324ureg->input[i].last = index + array_size - 1;325ureg->input[i].array_id = array_id;326ureg->input[i].usage_mask = usage_mask;327ureg->nr_input_regs = MAX2(ureg->nr_input_regs, index + array_size);328ureg->nr_inputs++;329} else {330set_bad(ureg);331}332333out:334return ureg_src_array_register(TGSI_FILE_INPUT, ureg->input[i].first,335array_id);336}337338struct ureg_src339ureg_DECL_fs_input_cyl_centroid(struct ureg_program *ureg,340enum tgsi_semantic semantic_name,341unsigned semantic_index,342enum tgsi_interpolate_mode interp_mode,343unsigned cylindrical_wrap,344enum tgsi_interpolate_loc interp_location,345unsigned array_id,346unsigned array_size)347{348return ureg_DECL_fs_input_cyl_centroid_layout(ureg,349semantic_name, semantic_index, interp_mode,350cylindrical_wrap, interp_location,351ureg->nr_input_regs, TGSI_WRITEMASK_XYZW, array_id, array_size);352}353354355struct ureg_src356ureg_DECL_vs_input( struct ureg_program *ureg,357unsigned index )358{359assert(ureg->processor == PIPE_SHADER_VERTEX);360assert(index / 32 < ARRAY_SIZE(ureg->vs_inputs));361362ureg->vs_inputs[index/32] |= 1 << (index % 32);363return ureg_src_register( TGSI_FILE_INPUT, index );364}365366367struct ureg_src368ureg_DECL_input_layout(struct ureg_program *ureg,369enum tgsi_semantic semantic_name,370unsigned semantic_index,371unsigned index,372unsigned usage_mask,373unsigned array_id,374unsigned array_size)375{376return ureg_DECL_fs_input_cyl_centroid_layout(ureg,377semantic_name, semantic_index,378TGSI_INTERPOLATE_CONSTANT, 0, TGSI_INTERPOLATE_LOC_CENTER,379index, usage_mask, array_id, array_size);380}381382383struct ureg_src384ureg_DECL_input(struct ureg_program *ureg,385enum tgsi_semantic semantic_name,386unsigned semantic_index,387unsigned array_id,388unsigned array_size)389{390return ureg_DECL_fs_input_cyl_centroid(ureg, semantic_name, semantic_index,391TGSI_INTERPOLATE_CONSTANT, 0,392TGSI_INTERPOLATE_LOC_CENTER,393array_id, array_size);394}395396397struct ureg_src398ureg_DECL_system_value(struct ureg_program *ureg,399enum tgsi_semantic semantic_name,400unsigned semantic_index)401{402unsigned i;403404for (i = 0; i < ureg->nr_system_values; i++) {405if (ureg->system_value[i].semantic_name == semantic_name &&406ureg->system_value[i].semantic_index == semantic_index) {407goto out;408}409}410411if (ureg->nr_system_values < UREG_MAX_SYSTEM_VALUE) {412ureg->system_value[ureg->nr_system_values].semantic_name = semantic_name;413ureg->system_value[ureg->nr_system_values].semantic_index = semantic_index;414i = ureg->nr_system_values;415ureg->nr_system_values++;416} else {417set_bad(ureg);418}419420out:421return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, i);422}423424425struct ureg_dst426ureg_DECL_output_layout(struct ureg_program *ureg,427enum tgsi_semantic semantic_name,428unsigned semantic_index,429unsigned streams,430unsigned index,431unsigned usage_mask,432unsigned array_id,433unsigned array_size,434boolean invariant)435{436unsigned i;437438assert(usage_mask != 0);439assert(!(streams & 0x03) || (usage_mask & 1));440assert(!(streams & 0x0c) || (usage_mask & 2));441assert(!(streams & 0x30) || (usage_mask & 4));442assert(!(streams & 0xc0) || (usage_mask & 8));443444for (i = 0; i < ureg->nr_outputs; i++) {445if (ureg->output[i].semantic_name == semantic_name &&446ureg->output[i].semantic_index == semantic_index) {447if (ureg->output[i].array_id == array_id) {448ureg->output[i].usage_mask |= usage_mask;449goto out;450}451assert((ureg->output[i].usage_mask & usage_mask) == 0);452}453}454455if (ureg->nr_outputs < UREG_MAX_OUTPUT) {456ureg->output[i].semantic_name = semantic_name;457ureg->output[i].semantic_index = semantic_index;458ureg->output[i].usage_mask = usage_mask;459ureg->output[i].first = index;460ureg->output[i].last = index + array_size - 1;461ureg->output[i].array_id = array_id;462ureg->output[i].invariant = invariant;463ureg->nr_output_regs = MAX2(ureg->nr_output_regs, index + array_size);464ureg->nr_outputs++;465}466else {467set_bad( ureg );468i = 0;469}470471out:472ureg->output[i].streams |= streams;473474return ureg_dst_array_register(TGSI_FILE_OUTPUT, ureg->output[i].first,475array_id);476}477478479struct ureg_dst480ureg_DECL_output_masked(struct ureg_program *ureg,481unsigned name,482unsigned index,483unsigned usage_mask,484unsigned array_id,485unsigned array_size)486{487return ureg_DECL_output_layout(ureg, name, index, 0,488ureg->nr_output_regs, usage_mask, array_id,489array_size, FALSE);490}491492493struct ureg_dst494ureg_DECL_output(struct ureg_program *ureg,495enum tgsi_semantic name,496unsigned index)497{498return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW,4990, 1);500}501502struct ureg_dst503ureg_DECL_output_array(struct ureg_program *ureg,504enum tgsi_semantic semantic_name,505unsigned semantic_index,506unsigned array_id,507unsigned array_size)508{509return ureg_DECL_output_masked(ureg, semantic_name, semantic_index,510TGSI_WRITEMASK_XYZW,511array_id, array_size);512}513514515/* Returns a new constant register. Keep track of which have been516* referred to so that we can emit decls later.517*518* Constant operands declared with this function must be addressed519* with a two-dimensional index.520*521* There is nothing in this code to bind this constant to any tracked522* value or manage any constant_buffer contents -- that's the523* resposibility of the calling code.524*/525void526ureg_DECL_constant2D(struct ureg_program *ureg,527unsigned first,528unsigned last,529unsigned index2D)530{531struct const_decl *decl = &ureg->const_decls[index2D];532533assert(index2D < PIPE_MAX_CONSTANT_BUFFERS);534535if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {536uint i = decl->nr_constant_ranges++;537538decl->constant_range[i].first = first;539decl->constant_range[i].last = last;540}541}542543544/* A one-dimensional, deprecated version of ureg_DECL_constant2D().545*546* Constant operands declared with this function must be addressed547* with a one-dimensional index.548*/549struct ureg_src550ureg_DECL_constant(struct ureg_program *ureg,551unsigned index)552{553struct const_decl *decl = &ureg->const_decls[0];554unsigned minconst = index, maxconst = index;555unsigned i;556557/* Inside existing range?558*/559for (i = 0; i < decl->nr_constant_ranges; i++) {560if (decl->constant_range[i].first <= index &&561decl->constant_range[i].last >= index) {562goto out;563}564}565566/* Extend existing range?567*/568for (i = 0; i < decl->nr_constant_ranges; i++) {569if (decl->constant_range[i].last == index - 1) {570decl->constant_range[i].last = index;571goto out;572}573574if (decl->constant_range[i].first == index + 1) {575decl->constant_range[i].first = index;576goto out;577}578579minconst = MIN2(minconst, decl->constant_range[i].first);580maxconst = MAX2(maxconst, decl->constant_range[i].last);581}582583/* Create new range?584*/585if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {586i = decl->nr_constant_ranges++;587decl->constant_range[i].first = index;588decl->constant_range[i].last = index;589goto out;590}591592/* Collapse all ranges down to one:593*/594i = 0;595decl->constant_range[0].first = minconst;596decl->constant_range[0].last = maxconst;597decl->nr_constant_ranges = 1;598599out:600assert(i < decl->nr_constant_ranges);601assert(decl->constant_range[i].first <= index);602assert(decl->constant_range[i].last >= index);603604struct ureg_src src = ureg_src_register(TGSI_FILE_CONSTANT, index);605return ureg_src_dimension(src, 0);606}607608609/* Returns a new hw atomic register. Keep track of which have been610* referred to so that we can emit decls later.611*/612void613ureg_DECL_hw_atomic(struct ureg_program *ureg,614unsigned first,615unsigned last,616unsigned buffer_id,617unsigned array_id)618{619struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[buffer_id];620621if (decl->nr_hw_atomic_ranges < UREG_MAX_HW_ATOMIC_RANGE) {622uint i = decl->nr_hw_atomic_ranges++;623624decl->hw_atomic_range[i].first = first;625decl->hw_atomic_range[i].last = last;626decl->hw_atomic_range[i].array_id = array_id;627} else {628set_bad(ureg);629}630}631632static struct ureg_dst alloc_temporary( struct ureg_program *ureg,633boolean local )634{635unsigned i;636637/* Look for a released temporary.638*/639for (i = util_bitmask_get_first_index(ureg->free_temps);640i != UTIL_BITMASK_INVALID_INDEX;641i = util_bitmask_get_next_index(ureg->free_temps, i + 1)) {642if (util_bitmask_get(ureg->local_temps, i) == local)643break;644}645646/* Or allocate a new one.647*/648if (i == UTIL_BITMASK_INVALID_INDEX) {649i = ureg->nr_temps++;650651if (local)652util_bitmask_set(ureg->local_temps, i);653654/* Start a new declaration when the local flag changes */655if (!i || util_bitmask_get(ureg->local_temps, i - 1) != local)656util_bitmask_set(ureg->decl_temps, i);657}658659util_bitmask_clear(ureg->free_temps, i);660661return ureg_dst_register( TGSI_FILE_TEMPORARY, i );662}663664struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg )665{666return alloc_temporary(ureg, FALSE);667}668669struct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg )670{671return alloc_temporary(ureg, TRUE);672}673674struct ureg_dst ureg_DECL_array_temporary( struct ureg_program *ureg,675unsigned size,676boolean local )677{678unsigned i = ureg->nr_temps;679struct ureg_dst dst = ureg_dst_register( TGSI_FILE_TEMPORARY, i );680681if (local)682util_bitmask_set(ureg->local_temps, i);683684/* Always start a new declaration at the start */685util_bitmask_set(ureg->decl_temps, i);686687ureg->nr_temps += size;688689/* and also at the end of the array */690util_bitmask_set(ureg->decl_temps, ureg->nr_temps);691692if (ureg->nr_array_temps < UREG_MAX_ARRAY_TEMPS) {693ureg->array_temps[ureg->nr_array_temps++] = i;694dst.ArrayID = ureg->nr_array_temps;695}696697return dst;698}699700void ureg_release_temporary( struct ureg_program *ureg,701struct ureg_dst tmp )702{703if(tmp.File == TGSI_FILE_TEMPORARY)704util_bitmask_set(ureg->free_temps, tmp.Index);705}706707708/* Allocate a new address register.709*/710struct ureg_dst ureg_DECL_address( struct ureg_program *ureg )711{712if (ureg->nr_addrs < UREG_MAX_ADDR)713return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ );714715assert( 0 );716return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );717}718719/* Allocate a new sampler.720*/721struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,722unsigned nr )723{724unsigned i;725726for (i = 0; i < ureg->nr_samplers; i++)727if (ureg->sampler[i].Index == (int)nr)728return ureg->sampler[i];729730if (i < PIPE_MAX_SAMPLERS) {731ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr );732ureg->nr_samplers++;733return ureg->sampler[i];734}735736assert( 0 );737return ureg->sampler[0];738}739740/*741* Allocate a new shader sampler view.742*/743struct ureg_src744ureg_DECL_sampler_view(struct ureg_program *ureg,745unsigned index,746enum tgsi_texture_type target,747enum tgsi_return_type return_type_x,748enum tgsi_return_type return_type_y,749enum tgsi_return_type return_type_z,750enum tgsi_return_type return_type_w)751{752struct ureg_src reg = ureg_src_register(TGSI_FILE_SAMPLER_VIEW, index);753uint i;754755for (i = 0; i < ureg->nr_sampler_views; i++) {756if (ureg->sampler_view[i].index == index) {757return reg;758}759}760761if (i < PIPE_MAX_SHADER_SAMPLER_VIEWS) {762ureg->sampler_view[i].index = index;763ureg->sampler_view[i].target = target;764ureg->sampler_view[i].return_type_x = return_type_x;765ureg->sampler_view[i].return_type_y = return_type_y;766ureg->sampler_view[i].return_type_z = return_type_z;767ureg->sampler_view[i].return_type_w = return_type_w;768ureg->nr_sampler_views++;769return reg;770}771772assert(0);773return reg;774}775776/* Allocate a new image.777*/778struct ureg_src779ureg_DECL_image(struct ureg_program *ureg,780unsigned index,781enum tgsi_texture_type target,782enum pipe_format format,783boolean wr,784boolean raw)785{786struct ureg_src reg = ureg_src_register(TGSI_FILE_IMAGE, index);787unsigned i;788789for (i = 0; i < ureg->nr_images; i++)790if (ureg->image[i].index == index)791return reg;792793if (i < PIPE_MAX_SHADER_IMAGES) {794ureg->image[i].index = index;795ureg->image[i].target = target;796ureg->image[i].wr = wr;797ureg->image[i].raw = raw;798ureg->image[i].format = format;799ureg->nr_images++;800return reg;801}802803assert(0);804return reg;805}806807/* Allocate a new buffer.808*/809struct ureg_src ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr,810bool atomic)811{812struct ureg_src reg = ureg_src_register(TGSI_FILE_BUFFER, nr);813unsigned i;814815for (i = 0; i < ureg->nr_buffers; i++)816if (ureg->buffer[i].index == nr)817return reg;818819if (i < PIPE_MAX_SHADER_BUFFERS) {820ureg->buffer[i].index = nr;821ureg->buffer[i].atomic = atomic;822ureg->nr_buffers++;823return reg;824}825826assert(0);827return reg;828}829830/* Allocate a memory area.831*/832struct ureg_src ureg_DECL_memory(struct ureg_program *ureg,833unsigned memory_type)834{835struct ureg_src reg = ureg_src_register(TGSI_FILE_MEMORY, memory_type);836837ureg->use_memory[memory_type] = true;838return reg;839}840841static int842match_or_expand_immediate64( const unsigned *v,843unsigned nr,844unsigned *v2,845unsigned *pnr2,846unsigned *swizzle )847{848unsigned nr2 = *pnr2;849unsigned i, j;850*swizzle = 0;851852for (i = 0; i < nr; i += 2) {853boolean found = FALSE;854855for (j = 0; j < nr2 && !found; j += 2) {856if (v[i] == v2[j] && v[i + 1] == v2[j + 1]) {857*swizzle |= (j << (i * 2)) | ((j + 1) << ((i + 1) * 2));858found = TRUE;859}860}861if (!found) {862if ((nr2) >= 4) {863return FALSE;864}865866v2[nr2] = v[i];867v2[nr2 + 1] = v[i + 1];868869*swizzle |= (nr2 << (i * 2)) | ((nr2 + 1) << ((i + 1) * 2));870nr2 += 2;871}872}873874/* Actually expand immediate only when fully succeeded.875*/876*pnr2 = nr2;877return TRUE;878}879880static int881match_or_expand_immediate( const unsigned *v,882int type,883unsigned nr,884unsigned *v2,885unsigned *pnr2,886unsigned *swizzle )887{888unsigned nr2 = *pnr2;889unsigned i, j;890891if (type == TGSI_IMM_FLOAT64 ||892type == TGSI_IMM_UINT64 ||893type == TGSI_IMM_INT64)894return match_or_expand_immediate64(v, nr, v2, pnr2, swizzle);895896*swizzle = 0;897898for (i = 0; i < nr; i++) {899boolean found = FALSE;900901for (j = 0; j < nr2 && !found; j++) {902if (v[i] == v2[j]) {903*swizzle |= j << (i * 2);904found = TRUE;905}906}907908if (!found) {909if (nr2 >= 4) {910return FALSE;911}912913v2[nr2] = v[i];914*swizzle |= nr2 << (i * 2);915nr2++;916}917}918919/* Actually expand immediate only when fully succeeded.920*/921*pnr2 = nr2;922return TRUE;923}924925926static struct ureg_src927decl_immediate( struct ureg_program *ureg,928const unsigned *v,929unsigned nr,930unsigned type )931{932unsigned i, j;933unsigned swizzle = 0;934935/* Could do a first pass where we examine all existing immediates936* without expanding.937*/938939for (i = 0; i < ureg->nr_immediates; i++) {940if (ureg->immediate[i].type != type) {941continue;942}943if (match_or_expand_immediate(v,944type,945nr,946ureg->immediate[i].value.u,947&ureg->immediate[i].nr,948&swizzle)) {949goto out;950}951}952953if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) {954i = ureg->nr_immediates++;955ureg->immediate[i].type = type;956if (match_or_expand_immediate(v,957type,958nr,959ureg->immediate[i].value.u,960&ureg->immediate[i].nr,961&swizzle)) {962goto out;963}964}965966set_bad(ureg);967968out:969/* Make sure that all referenced elements are from this immediate.970* Has the effect of making size-one immediates into scalars.971*/972if (type == TGSI_IMM_FLOAT64 ||973type == TGSI_IMM_UINT64 ||974type == TGSI_IMM_INT64) {975for (j = nr; j < 4; j+=2) {976swizzle |= (swizzle & 0xf) << (j * 2);977}978} else {979for (j = nr; j < 4; j++) {980swizzle |= (swizzle & 0x3) << (j * 2);981}982}983return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i),984(swizzle >> 0) & 0x3,985(swizzle >> 2) & 0x3,986(swizzle >> 4) & 0x3,987(swizzle >> 6) & 0x3);988}989990991struct ureg_src992ureg_DECL_immediate( struct ureg_program *ureg,993const float *v,994unsigned nr )995{996union {997float f[4];998unsigned u[4];999} fu;1000unsigned int i;10011002for (i = 0; i < nr; i++) {1003fu.f[i] = v[i];1004}10051006return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32);1007}10081009struct ureg_src1010ureg_DECL_immediate_f64( struct ureg_program *ureg,1011const double *v,1012unsigned nr )1013{1014union {1015unsigned u[4];1016double d[2];1017} fu;1018unsigned int i;10191020assert((nr / 2) < 3);1021for (i = 0; i < nr / 2; i++) {1022fu.d[i] = v[i];1023}10241025return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT64);1026}10271028struct ureg_src1029ureg_DECL_immediate_uint( struct ureg_program *ureg,1030const unsigned *v,1031unsigned nr )1032{1033return decl_immediate(ureg, v, nr, TGSI_IMM_UINT32);1034}103510361037struct ureg_src1038ureg_DECL_immediate_block_uint( struct ureg_program *ureg,1039const unsigned *v,1040unsigned nr )1041{1042uint index;1043uint i;10441045if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) {1046set_bad(ureg);1047return ureg_src_register(TGSI_FILE_IMMEDIATE, 0);1048}10491050index = ureg->nr_immediates;1051ureg->nr_immediates += (nr + 3) / 4;10521053for (i = index; i < ureg->nr_immediates; i++) {1054ureg->immediate[i].type = TGSI_IMM_UINT32;1055ureg->immediate[i].nr = nr > 4 ? 4 : nr;1056memcpy(ureg->immediate[i].value.u,1057&v[(i - index) * 4],1058ureg->immediate[i].nr * sizeof(uint));1059nr -= 4;1060}10611062return ureg_src_register(TGSI_FILE_IMMEDIATE, index);1063}106410651066struct ureg_src1067ureg_DECL_immediate_int( struct ureg_program *ureg,1068const int *v,1069unsigned nr )1070{1071return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32);1072}10731074struct ureg_src1075ureg_DECL_immediate_uint64( struct ureg_program *ureg,1076const uint64_t *v,1077unsigned nr )1078{1079union {1080unsigned u[4];1081uint64_t u64[2];1082} fu;1083unsigned int i;10841085assert((nr / 2) < 3);1086for (i = 0; i < nr / 2; i++) {1087fu.u64[i] = v[i];1088}10891090return decl_immediate(ureg, fu.u, nr, TGSI_IMM_UINT64);1091}10921093struct ureg_src1094ureg_DECL_immediate_int64( struct ureg_program *ureg,1095const int64_t *v,1096unsigned nr )1097{1098union {1099unsigned u[4];1100int64_t i64[2];1101} fu;1102unsigned int i;11031104assert((nr / 2) < 3);1105for (i = 0; i < nr / 2; i++) {1106fu.i64[i] = v[i];1107}11081109return decl_immediate(ureg, fu.u, nr, TGSI_IMM_INT64);1110}11111112void1113ureg_emit_src( struct ureg_program *ureg,1114struct ureg_src src )1115{1116unsigned size = 1 + (src.Indirect ? 1 : 0) +1117(src.Dimension ? (src.DimIndirect ? 2 : 1) : 0);11181119union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );1120unsigned n = 0;11211122assert(src.File != TGSI_FILE_NULL);1123assert(src.File < TGSI_FILE_COUNT);11241125out[n].value = 0;1126out[n].src.File = src.File;1127out[n].src.SwizzleX = src.SwizzleX;1128out[n].src.SwizzleY = src.SwizzleY;1129out[n].src.SwizzleZ = src.SwizzleZ;1130out[n].src.SwizzleW = src.SwizzleW;1131out[n].src.Index = src.Index;1132out[n].src.Negate = src.Negate;1133out[0].src.Absolute = src.Absolute;1134n++;11351136if (src.Indirect) {1137out[0].src.Indirect = 1;1138out[n].value = 0;1139out[n].ind.File = src.IndirectFile;1140out[n].ind.Swizzle = src.IndirectSwizzle;1141out[n].ind.Index = src.IndirectIndex;1142if (!ureg->supports_any_inout_decl_range &&1143(src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT))1144out[n].ind.ArrayID = 0;1145else1146out[n].ind.ArrayID = src.ArrayID;1147n++;1148}11491150if (src.Dimension) {1151out[0].src.Dimension = 1;1152out[n].dim.Dimension = 0;1153out[n].dim.Padding = 0;1154if (src.DimIndirect) {1155out[n].dim.Indirect = 1;1156out[n].dim.Index = src.DimensionIndex;1157n++;1158out[n].value = 0;1159out[n].ind.File = src.DimIndFile;1160out[n].ind.Swizzle = src.DimIndSwizzle;1161out[n].ind.Index = src.DimIndIndex;1162if (!ureg->supports_any_inout_decl_range &&1163(src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT))1164out[n].ind.ArrayID = 0;1165else1166out[n].ind.ArrayID = src.ArrayID;1167} else {1168out[n].dim.Indirect = 0;1169out[n].dim.Index = src.DimensionIndex;1170}1171n++;1172}11731174assert(n == size);1175}117611771178void1179ureg_emit_dst( struct ureg_program *ureg,1180struct ureg_dst dst )1181{1182unsigned size = 1 + (dst.Indirect ? 1 : 0) +1183(dst.Dimension ? (dst.DimIndirect ? 2 : 1) : 0);11841185union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );1186unsigned n = 0;11871188assert(dst.File != TGSI_FILE_NULL);1189assert(dst.File != TGSI_FILE_SAMPLER);1190assert(dst.File != TGSI_FILE_SAMPLER_VIEW);1191assert(dst.File != TGSI_FILE_IMMEDIATE);1192assert(dst.File < TGSI_FILE_COUNT);11931194out[n].value = 0;1195out[n].dst.File = dst.File;1196out[n].dst.WriteMask = dst.WriteMask;1197out[n].dst.Indirect = dst.Indirect;1198out[n].dst.Index = dst.Index;1199n++;12001201if (dst.Indirect) {1202out[n].value = 0;1203out[n].ind.File = dst.IndirectFile;1204out[n].ind.Swizzle = dst.IndirectSwizzle;1205out[n].ind.Index = dst.IndirectIndex;1206if (!ureg->supports_any_inout_decl_range &&1207(dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT))1208out[n].ind.ArrayID = 0;1209else1210out[n].ind.ArrayID = dst.ArrayID;1211n++;1212}12131214if (dst.Dimension) {1215out[0].dst.Dimension = 1;1216out[n].dim.Dimension = 0;1217out[n].dim.Padding = 0;1218if (dst.DimIndirect) {1219out[n].dim.Indirect = 1;1220out[n].dim.Index = dst.DimensionIndex;1221n++;1222out[n].value = 0;1223out[n].ind.File = dst.DimIndFile;1224out[n].ind.Swizzle = dst.DimIndSwizzle;1225out[n].ind.Index = dst.DimIndIndex;1226if (!ureg->supports_any_inout_decl_range &&1227(dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT))1228out[n].ind.ArrayID = 0;1229else1230out[n].ind.ArrayID = dst.ArrayID;1231} else {1232out[n].dim.Indirect = 0;1233out[n].dim.Index = dst.DimensionIndex;1234}1235n++;1236}12371238assert(n == size);1239}124012411242static void validate( enum tgsi_opcode opcode,1243unsigned nr_dst,1244unsigned nr_src )1245{1246#ifndef NDEBUG1247const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );1248assert(info);1249if (info) {1250assert(nr_dst == info->num_dst);1251assert(nr_src == info->num_src);1252}1253#endif1254}12551256struct ureg_emit_insn_result1257ureg_emit_insn(struct ureg_program *ureg,1258enum tgsi_opcode opcode,1259boolean saturate,1260unsigned precise,1261unsigned num_dst,1262unsigned num_src)1263{1264union tgsi_any_token *out;1265uint count = 1;1266struct ureg_emit_insn_result result;12671268validate( opcode, num_dst, num_src );12691270out = get_tokens( ureg, DOMAIN_INSN, count );1271out[0].insn = tgsi_default_instruction();1272out[0].insn.Opcode = opcode;1273out[0].insn.Saturate = saturate;1274out[0].insn.Precise = precise;1275out[0].insn.NumDstRegs = num_dst;1276out[0].insn.NumSrcRegs = num_src;12771278result.insn_token = ureg->domain[DOMAIN_INSN].count - count;1279result.extended_token = result.insn_token;12801281ureg->nr_instructions++;12821283return result;1284}128512861287/**1288* Emit a label token.1289* \param label_token returns a token number indicating where the label1290* needs to be patched later. Later, this value should be passed to the1291* ureg_fixup_label() function.1292*/1293void1294ureg_emit_label(struct ureg_program *ureg,1295unsigned extended_token,1296unsigned *label_token )1297{1298union tgsi_any_token *out, *insn;12991300if (!label_token)1301return;13021303out = get_tokens( ureg, DOMAIN_INSN, 1 );1304out[0].value = 0;13051306insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );1307insn->insn.Label = 1;13081309*label_token = ureg->domain[DOMAIN_INSN].count - 1;1310}13111312/* Will return a number which can be used in a label to point to the1313* next instruction to be emitted.1314*/1315unsigned1316ureg_get_instruction_number( struct ureg_program *ureg )1317{1318return ureg->nr_instructions;1319}13201321/* Patch a given label (expressed as a token number) to point to a1322* given instruction (expressed as an instruction number).1323*/1324void1325ureg_fixup_label(struct ureg_program *ureg,1326unsigned label_token,1327unsigned instruction_number )1328{1329union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token );13301331out->insn_label.Label = instruction_number;1332}133313341335void1336ureg_emit_texture(struct ureg_program *ureg,1337unsigned extended_token,1338enum tgsi_texture_type target,1339enum tgsi_return_type return_type, unsigned num_offsets)1340{1341union tgsi_any_token *out, *insn;13421343out = get_tokens( ureg, DOMAIN_INSN, 1 );1344insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );13451346insn->insn.Texture = 1;13471348out[0].value = 0;1349out[0].insn_texture.Texture = target;1350out[0].insn_texture.NumOffsets = num_offsets;1351out[0].insn_texture.ReturnType = return_type;1352}13531354void1355ureg_emit_texture_offset(struct ureg_program *ureg,1356const struct tgsi_texture_offset *offset)1357{1358union tgsi_any_token *out;13591360out = get_tokens( ureg, DOMAIN_INSN, 1);13611362out[0].value = 0;1363out[0].insn_texture_offset = *offset;1364}13651366void1367ureg_emit_memory(struct ureg_program *ureg,1368unsigned extended_token,1369unsigned qualifier,1370enum tgsi_texture_type texture,1371enum pipe_format format)1372{1373union tgsi_any_token *out, *insn;13741375out = get_tokens( ureg, DOMAIN_INSN, 1 );1376insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );13771378insn->insn.Memory = 1;13791380out[0].value = 0;1381out[0].insn_memory.Qualifier = qualifier;1382out[0].insn_memory.Texture = texture;1383out[0].insn_memory.Format = format;1384}13851386void1387ureg_fixup_insn_size(struct ureg_program *ureg,1388unsigned insn )1389{1390union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn );13911392assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION);1393out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;1394}139513961397void1398ureg_insn(struct ureg_program *ureg,1399enum tgsi_opcode opcode,1400const struct ureg_dst *dst,1401unsigned nr_dst,1402const struct ureg_src *src,1403unsigned nr_src,1404unsigned precise )1405{1406struct ureg_emit_insn_result insn;1407unsigned i;1408boolean saturate;14091410if (nr_dst && ureg_dst_is_empty(dst[0])) {1411return;1412}14131414saturate = nr_dst ? dst[0].Saturate : FALSE;14151416insn = ureg_emit_insn(ureg,1417opcode,1418saturate,1419precise,1420nr_dst,1421nr_src);14221423for (i = 0; i < nr_dst; i++)1424ureg_emit_dst( ureg, dst[i] );14251426for (i = 0; i < nr_src; i++)1427ureg_emit_src( ureg, src[i] );14281429ureg_fixup_insn_size( ureg, insn.insn_token );1430}14311432void1433ureg_tex_insn(struct ureg_program *ureg,1434enum tgsi_opcode opcode,1435const struct ureg_dst *dst,1436unsigned nr_dst,1437enum tgsi_texture_type target,1438enum tgsi_return_type return_type,1439const struct tgsi_texture_offset *texoffsets,1440unsigned nr_offset,1441const struct ureg_src *src,1442unsigned nr_src )1443{1444struct ureg_emit_insn_result insn;1445unsigned i;1446boolean saturate;14471448if (nr_dst && ureg_dst_is_empty(dst[0])) {1449return;1450}14511452saturate = nr_dst ? dst[0].Saturate : FALSE;14531454insn = ureg_emit_insn(ureg,1455opcode,1456saturate,14570,1458nr_dst,1459nr_src);14601461ureg_emit_texture( ureg, insn.extended_token, target, return_type,1462nr_offset );14631464for (i = 0; i < nr_offset; i++)1465ureg_emit_texture_offset( ureg, &texoffsets[i]);14661467for (i = 0; i < nr_dst; i++)1468ureg_emit_dst( ureg, dst[i] );14691470for (i = 0; i < nr_src; i++)1471ureg_emit_src( ureg, src[i] );14721473ureg_fixup_insn_size( ureg, insn.insn_token );1474}147514761477void1478ureg_memory_insn(struct ureg_program *ureg,1479enum tgsi_opcode opcode,1480const struct ureg_dst *dst,1481unsigned nr_dst,1482const struct ureg_src *src,1483unsigned nr_src,1484unsigned qualifier,1485enum tgsi_texture_type texture,1486enum pipe_format format)1487{1488struct ureg_emit_insn_result insn;1489unsigned i;14901491insn = ureg_emit_insn(ureg,1492opcode,1493FALSE,14940,1495nr_dst,1496nr_src);14971498ureg_emit_memory(ureg, insn.extended_token, qualifier, texture, format);14991500for (i = 0; i < nr_dst; i++)1501ureg_emit_dst(ureg, dst[i]);15021503for (i = 0; i < nr_src; i++)1504ureg_emit_src(ureg, src[i]);15051506ureg_fixup_insn_size(ureg, insn.insn_token);1507}150815091510static void1511emit_decl_semantic(struct ureg_program *ureg,1512unsigned file,1513unsigned first,1514unsigned last,1515enum tgsi_semantic semantic_name,1516unsigned semantic_index,1517unsigned streams,1518unsigned usage_mask,1519unsigned array_id,1520boolean invariant)1521{1522union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);15231524out[0].value = 0;1525out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1526out[0].decl.NrTokens = 3;1527out[0].decl.File = file;1528out[0].decl.UsageMask = usage_mask;1529out[0].decl.Semantic = 1;1530out[0].decl.Array = array_id != 0;1531out[0].decl.Invariant = invariant;15321533out[1].value = 0;1534out[1].decl_range.First = first;1535out[1].decl_range.Last = last;15361537out[2].value = 0;1538out[2].decl_semantic.Name = semantic_name;1539out[2].decl_semantic.Index = semantic_index;1540out[2].decl_semantic.StreamX = streams & 3;1541out[2].decl_semantic.StreamY = (streams >> 2) & 3;1542out[2].decl_semantic.StreamZ = (streams >> 4) & 3;1543out[2].decl_semantic.StreamW = (streams >> 6) & 3;15441545if (array_id) {1546out[3].value = 0;1547out[3].array.ArrayID = array_id;1548}1549}15501551static void1552emit_decl_atomic_2d(struct ureg_program *ureg,1553unsigned first,1554unsigned last,1555unsigned index2D,1556unsigned array_id)1557{1558union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);15591560out[0].value = 0;1561out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1562out[0].decl.NrTokens = 3;1563out[0].decl.File = TGSI_FILE_HW_ATOMIC;1564out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;1565out[0].decl.Dimension = 1;1566out[0].decl.Array = array_id != 0;15671568out[1].value = 0;1569out[1].decl_range.First = first;1570out[1].decl_range.Last = last;15711572out[2].value = 0;1573out[2].decl_dim.Index2D = index2D;15741575if (array_id) {1576out[3].value = 0;1577out[3].array.ArrayID = array_id;1578}1579}15801581static void1582emit_decl_fs(struct ureg_program *ureg,1583unsigned file,1584unsigned first,1585unsigned last,1586enum tgsi_semantic semantic_name,1587unsigned semantic_index,1588enum tgsi_interpolate_mode interpolate,1589unsigned cylindrical_wrap,1590enum tgsi_interpolate_loc interpolate_location,1591unsigned array_id,1592unsigned usage_mask)1593{1594union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL,1595array_id ? 5 : 4);15961597out[0].value = 0;1598out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1599out[0].decl.NrTokens = 4;1600out[0].decl.File = file;1601out[0].decl.UsageMask = usage_mask;1602out[0].decl.Interpolate = 1;1603out[0].decl.Semantic = 1;1604out[0].decl.Array = array_id != 0;16051606out[1].value = 0;1607out[1].decl_range.First = first;1608out[1].decl_range.Last = last;16091610out[2].value = 0;1611out[2].decl_interp.Interpolate = interpolate;1612out[2].decl_interp.CylindricalWrap = cylindrical_wrap;1613out[2].decl_interp.Location = interpolate_location;16141615out[3].value = 0;1616out[3].decl_semantic.Name = semantic_name;1617out[3].decl_semantic.Index = semantic_index;16181619if (array_id) {1620out[4].value = 0;1621out[4].array.ArrayID = array_id;1622}1623}16241625static void1626emit_decl_temps( struct ureg_program *ureg,1627unsigned first, unsigned last,1628boolean local,1629unsigned arrayid )1630{1631union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL,1632arrayid ? 3 : 2 );16331634out[0].value = 0;1635out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1636out[0].decl.NrTokens = 2;1637out[0].decl.File = TGSI_FILE_TEMPORARY;1638out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;1639out[0].decl.Local = local;16401641out[1].value = 0;1642out[1].decl_range.First = first;1643out[1].decl_range.Last = last;16441645if (arrayid) {1646out[0].decl.Array = 1;1647out[2].value = 0;1648out[2].array.ArrayID = arrayid;1649}1650}16511652static void emit_decl_range( struct ureg_program *ureg,1653unsigned file,1654unsigned first,1655unsigned count )1656{1657union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );16581659out[0].value = 0;1660out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1661out[0].decl.NrTokens = 2;1662out[0].decl.File = file;1663out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;1664out[0].decl.Semantic = 0;16651666out[1].value = 0;1667out[1].decl_range.First = first;1668out[1].decl_range.Last = first + count - 1;1669}16701671static void1672emit_decl_range2D(struct ureg_program *ureg,1673unsigned file,1674unsigned first,1675unsigned last,1676unsigned index2D)1677{1678union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);16791680out[0].value = 0;1681out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1682out[0].decl.NrTokens = 3;1683out[0].decl.File = file;1684out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;1685out[0].decl.Dimension = 1;16861687out[1].value = 0;1688out[1].decl_range.First = first;1689out[1].decl_range.Last = last;16901691out[2].value = 0;1692out[2].decl_dim.Index2D = index2D;1693}16941695static void1696emit_decl_sampler_view(struct ureg_program *ureg,1697unsigned index,1698enum tgsi_texture_type target,1699enum tgsi_return_type return_type_x,1700enum tgsi_return_type return_type_y,1701enum tgsi_return_type return_type_z,1702enum tgsi_return_type return_type_w )1703{1704union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);17051706out[0].value = 0;1707out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1708out[0].decl.NrTokens = 3;1709out[0].decl.File = TGSI_FILE_SAMPLER_VIEW;1710out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;17111712out[1].value = 0;1713out[1].decl_range.First = index;1714out[1].decl_range.Last = index;17151716out[2].value = 0;1717out[2].decl_sampler_view.Resource = target;1718out[2].decl_sampler_view.ReturnTypeX = return_type_x;1719out[2].decl_sampler_view.ReturnTypeY = return_type_y;1720out[2].decl_sampler_view.ReturnTypeZ = return_type_z;1721out[2].decl_sampler_view.ReturnTypeW = return_type_w;1722}17231724static void1725emit_decl_image(struct ureg_program *ureg,1726unsigned index,1727enum tgsi_texture_type target,1728enum pipe_format format,1729boolean wr,1730boolean raw)1731{1732union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);17331734out[0].value = 0;1735out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1736out[0].decl.NrTokens = 3;1737out[0].decl.File = TGSI_FILE_IMAGE;1738out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;17391740out[1].value = 0;1741out[1].decl_range.First = index;1742out[1].decl_range.Last = index;17431744out[2].value = 0;1745out[2].decl_image.Resource = target;1746out[2].decl_image.Writable = wr;1747out[2].decl_image.Raw = raw;1748out[2].decl_image.Format = format;1749}17501751static void1752emit_decl_buffer(struct ureg_program *ureg,1753unsigned index,1754bool atomic)1755{1756union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);17571758out[0].value = 0;1759out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1760out[0].decl.NrTokens = 2;1761out[0].decl.File = TGSI_FILE_BUFFER;1762out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;1763out[0].decl.Atomic = atomic;17641765out[1].value = 0;1766out[1].decl_range.First = index;1767out[1].decl_range.Last = index;1768}17691770static void1771emit_decl_memory(struct ureg_program *ureg, unsigned memory_type)1772{1773union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);17741775out[0].value = 0;1776out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;1777out[0].decl.NrTokens = 2;1778out[0].decl.File = TGSI_FILE_MEMORY;1779out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;1780out[0].decl.MemType = memory_type;17811782out[1].value = 0;1783out[1].decl_range.First = memory_type;1784out[1].decl_range.Last = memory_type;1785}17861787static void1788emit_immediate( struct ureg_program *ureg,1789const unsigned *v,1790unsigned type )1791{1792union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );17931794out[0].value = 0;1795out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;1796out[0].imm.NrTokens = 5;1797out[0].imm.DataType = type;1798out[0].imm.Padding = 0;17991800out[1].imm_data.Uint = v[0];1801out[2].imm_data.Uint = v[1];1802out[3].imm_data.Uint = v[2];1803out[4].imm_data.Uint = v[3];1804}18051806static void1807emit_property(struct ureg_program *ureg,1808unsigned name,1809unsigned data)1810{1811union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);18121813out[0].value = 0;1814out[0].prop.Type = TGSI_TOKEN_TYPE_PROPERTY;1815out[0].prop.NrTokens = 2;1816out[0].prop.PropertyName = name;18171818out[1].prop_data.Data = data;1819}182018211822static void emit_decls( struct ureg_program *ureg )1823{1824unsigned i,j;18251826for (i = 0; i < ARRAY_SIZE(ureg->properties); i++)1827if (ureg->properties[i] != ~0u)1828emit_property(ureg, i, ureg->properties[i]);18291830if (ureg->processor == PIPE_SHADER_VERTEX) {1831for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {1832if (ureg->vs_inputs[i/32] & (1u << (i%32))) {1833emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );1834}1835}1836} else if (ureg->processor == PIPE_SHADER_FRAGMENT) {1837if (ureg->supports_any_inout_decl_range) {1838for (i = 0; i < ureg->nr_inputs; i++) {1839emit_decl_fs(ureg,1840TGSI_FILE_INPUT,1841ureg->input[i].first,1842ureg->input[i].last,1843ureg->input[i].semantic_name,1844ureg->input[i].semantic_index,1845ureg->input[i].interp,1846ureg->input[i].cylindrical_wrap,1847ureg->input[i].interp_location,1848ureg->input[i].array_id,1849ureg->input[i].usage_mask);1850}1851}1852else {1853for (i = 0; i < ureg->nr_inputs; i++) {1854for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {1855emit_decl_fs(ureg,1856TGSI_FILE_INPUT,1857j, j,1858ureg->input[i].semantic_name,1859ureg->input[i].semantic_index +1860(j - ureg->input[i].first),1861ureg->input[i].interp,1862ureg->input[i].cylindrical_wrap,1863ureg->input[i].interp_location, 0,1864ureg->input[i].usage_mask);1865}1866}1867}1868} else {1869if (ureg->supports_any_inout_decl_range) {1870for (i = 0; i < ureg->nr_inputs; i++) {1871emit_decl_semantic(ureg,1872TGSI_FILE_INPUT,1873ureg->input[i].first,1874ureg->input[i].last,1875ureg->input[i].semantic_name,1876ureg->input[i].semantic_index,18770,1878TGSI_WRITEMASK_XYZW,1879ureg->input[i].array_id,1880FALSE);1881}1882}1883else {1884for (i = 0; i < ureg->nr_inputs; i++) {1885for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {1886emit_decl_semantic(ureg,1887TGSI_FILE_INPUT,1888j, j,1889ureg->input[i].semantic_name,1890ureg->input[i].semantic_index +1891(j - ureg->input[i].first),18920,1893TGSI_WRITEMASK_XYZW, 0, FALSE);1894}1895}1896}1897}18981899for (i = 0; i < ureg->nr_system_values; i++) {1900emit_decl_semantic(ureg,1901TGSI_FILE_SYSTEM_VALUE,1902i,1903i,1904ureg->system_value[i].semantic_name,1905ureg->system_value[i].semantic_index,19060,1907TGSI_WRITEMASK_XYZW, 0, FALSE);1908}19091910if (ureg->supports_any_inout_decl_range) {1911for (i = 0; i < ureg->nr_outputs; i++) {1912emit_decl_semantic(ureg,1913TGSI_FILE_OUTPUT,1914ureg->output[i].first,1915ureg->output[i].last,1916ureg->output[i].semantic_name,1917ureg->output[i].semantic_index,1918ureg->output[i].streams,1919ureg->output[i].usage_mask,1920ureg->output[i].array_id,1921ureg->output[i].invariant);1922}1923}1924else {1925for (i = 0; i < ureg->nr_outputs; i++) {1926for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) {1927emit_decl_semantic(ureg,1928TGSI_FILE_OUTPUT,1929j, j,1930ureg->output[i].semantic_name,1931ureg->output[i].semantic_index +1932(j - ureg->output[i].first),1933ureg->output[i].streams,1934ureg->output[i].usage_mask,19350,1936ureg->output[i].invariant);1937}1938}1939}19401941for (i = 0; i < ureg->nr_samplers; i++) {1942emit_decl_range( ureg,1943TGSI_FILE_SAMPLER,1944ureg->sampler[i].Index, 1 );1945}19461947for (i = 0; i < ureg->nr_sampler_views; i++) {1948emit_decl_sampler_view(ureg,1949ureg->sampler_view[i].index,1950ureg->sampler_view[i].target,1951ureg->sampler_view[i].return_type_x,1952ureg->sampler_view[i].return_type_y,1953ureg->sampler_view[i].return_type_z,1954ureg->sampler_view[i].return_type_w);1955}19561957for (i = 0; i < ureg->nr_images; i++) {1958emit_decl_image(ureg,1959ureg->image[i].index,1960ureg->image[i].target,1961ureg->image[i].format,1962ureg->image[i].wr,1963ureg->image[i].raw);1964}19651966for (i = 0; i < ureg->nr_buffers; i++) {1967emit_decl_buffer(ureg, ureg->buffer[i].index, ureg->buffer[i].atomic);1968}19691970for (i = 0; i < TGSI_MEMORY_TYPE_COUNT; i++) {1971if (ureg->use_memory[i])1972emit_decl_memory(ureg, i);1973}19741975for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {1976struct const_decl *decl = &ureg->const_decls[i];19771978if (decl->nr_constant_ranges) {1979uint j;19801981for (j = 0; j < decl->nr_constant_ranges; j++) {1982emit_decl_range2D(ureg,1983TGSI_FILE_CONSTANT,1984decl->constant_range[j].first,1985decl->constant_range[j].last,1986i);1987}1988}1989}19901991for (i = 0; i < PIPE_MAX_HW_ATOMIC_BUFFERS; i++) {1992struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[i];19931994if (decl->nr_hw_atomic_ranges) {1995uint j;19961997for (j = 0; j < decl->nr_hw_atomic_ranges; j++) {1998emit_decl_atomic_2d(ureg,1999decl->hw_atomic_range[j].first,2000decl->hw_atomic_range[j].last,2001i,2002decl->hw_atomic_range[j].array_id);2003}2004}2005}20062007if (ureg->nr_temps) {2008unsigned array = 0;2009for (i = 0; i < ureg->nr_temps;) {2010boolean local = util_bitmask_get(ureg->local_temps, i);2011unsigned first = i;2012i = util_bitmask_get_next_index(ureg->decl_temps, i + 1);2013if (i == UTIL_BITMASK_INVALID_INDEX)2014i = ureg->nr_temps;20152016if (array < ureg->nr_array_temps && ureg->array_temps[array] == first)2017emit_decl_temps( ureg, first, i - 1, local, ++array );2018else2019emit_decl_temps( ureg, first, i - 1, local, 0 );2020}2021}20222023if (ureg->nr_addrs) {2024emit_decl_range( ureg,2025TGSI_FILE_ADDRESS,20260, ureg->nr_addrs );2027}20282029for (i = 0; i < ureg->nr_immediates; i++) {2030emit_immediate( ureg,2031ureg->immediate[i].value.u,2032ureg->immediate[i].type );2033}2034}20352036/* Append the instruction tokens onto the declarations to build a2037* contiguous stream suitable to send to the driver.2038*/2039static void copy_instructions( struct ureg_program *ureg )2040{2041unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count;2042union tgsi_any_token *out = get_tokens( ureg,2043DOMAIN_DECL,2044nr_tokens );20452046memcpy(out,2047ureg->domain[DOMAIN_INSN].tokens,2048nr_tokens * sizeof out[0] );2049}205020512052static void2053fixup_header_size(struct ureg_program *ureg)2054{2055union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 0 );20562057out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 2;2058}205920602061static void2062emit_header( struct ureg_program *ureg )2063{2064union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );20652066out[0].header.HeaderSize = 2;2067out[0].header.BodySize = 0;20682069out[1].processor.Processor = ureg->processor;2070out[1].processor.Padding = 0;2071}207220732074const struct tgsi_token *ureg_finalize( struct ureg_program *ureg )2075{2076const struct tgsi_token *tokens;20772078switch (ureg->processor) {2079case PIPE_SHADER_VERTEX:2080case PIPE_SHADER_TESS_EVAL:2081ureg_property(ureg, TGSI_PROPERTY_NEXT_SHADER,2082ureg->next_shader_processor == -1 ?2083PIPE_SHADER_FRAGMENT :2084ureg->next_shader_processor);2085break;2086default:2087; /* nothing */2088}20892090emit_header( ureg );2091emit_decls( ureg );2092copy_instructions( ureg );2093fixup_header_size( ureg );20942095if (ureg->domain[0].tokens == error_tokens ||2096ureg->domain[1].tokens == error_tokens) {2097debug_printf("%s: error in generated shader\n", __FUNCTION__);2098assert(0);2099return NULL;2100}21012102tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;21032104if (0) {2105debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__,2106ureg->domain[DOMAIN_DECL].count);2107tgsi_dump( tokens, 0 );2108}21092110#if DEBUG2111/* tgsi_sanity doesn't seem to return if there are too many constants. */2112bool too_many_constants = false;2113for (unsigned i = 0; i < ARRAY_SIZE(ureg->const_decls); i++) {2114for (unsigned j = 0; j < ureg->const_decls[i].nr_constant_ranges; j++) {2115if (ureg->const_decls[i].constant_range[j].last > 4096) {2116too_many_constants = true;2117break;2118}2119}2120}21212122if (tokens && !too_many_constants && !tgsi_sanity_check(tokens)) {2123debug_printf("tgsi_ureg.c, sanity check failed on generated tokens:\n");2124tgsi_dump(tokens, 0);2125assert(0);2126}2127#endif212821292130return tokens;2131}213221332134void *ureg_create_shader( struct ureg_program *ureg,2135struct pipe_context *pipe,2136const struct pipe_stream_output_info *so )2137{2138struct pipe_shader_state state = {0};21392140pipe_shader_state_from_tgsi(&state, ureg_finalize(ureg));2141if(!state.tokens)2142return NULL;21432144if (so)2145state.stream_output = *so;21462147switch (ureg->processor) {2148case PIPE_SHADER_VERTEX:2149return pipe->create_vs_state(pipe, &state);2150case PIPE_SHADER_TESS_CTRL:2151return pipe->create_tcs_state(pipe, &state);2152case PIPE_SHADER_TESS_EVAL:2153return pipe->create_tes_state(pipe, &state);2154case PIPE_SHADER_GEOMETRY:2155return pipe->create_gs_state(pipe, &state);2156case PIPE_SHADER_FRAGMENT:2157return pipe->create_fs_state(pipe, &state);2158default:2159return NULL;2160}2161}216221632164const struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg,2165unsigned *nr_tokens )2166{2167const struct tgsi_token *tokens;21682169ureg_finalize(ureg);21702171tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;21722173if (nr_tokens)2174*nr_tokens = ureg->domain[DOMAIN_DECL].count;21752176ureg->domain[DOMAIN_DECL].tokens = 0;2177ureg->domain[DOMAIN_DECL].size = 0;2178ureg->domain[DOMAIN_DECL].order = 0;2179ureg->domain[DOMAIN_DECL].count = 0;21802181return tokens;2182}218321842185void ureg_free_tokens( const struct tgsi_token *tokens )2186{2187FREE((struct tgsi_token *)tokens);2188}218921902191struct ureg_program *2192ureg_create(enum pipe_shader_type processor)2193{2194return ureg_create_with_screen(processor, NULL);2195}219621972198struct ureg_program *2199ureg_create_with_screen(enum pipe_shader_type processor,2200struct pipe_screen *screen)2201{2202uint i;2203struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );2204if (!ureg)2205goto no_ureg;22062207ureg->processor = processor;2208ureg->supports_any_inout_decl_range =2209screen &&2210screen->get_shader_param(screen, processor,2211PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE) != 0;2212ureg->next_shader_processor = -1;22132214for (i = 0; i < ARRAY_SIZE(ureg->properties); i++)2215ureg->properties[i] = ~0;22162217ureg->free_temps = util_bitmask_create();2218if (ureg->free_temps == NULL)2219goto no_free_temps;22202221ureg->local_temps = util_bitmask_create();2222if (ureg->local_temps == NULL)2223goto no_local_temps;22242225ureg->decl_temps = util_bitmask_create();2226if (ureg->decl_temps == NULL)2227goto no_decl_temps;22282229return ureg;22302231no_decl_temps:2232util_bitmask_destroy(ureg->local_temps);2233no_local_temps:2234util_bitmask_destroy(ureg->free_temps);2235no_free_temps:2236FREE(ureg);2237no_ureg:2238return NULL;2239}224022412242void2243ureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor)2244{2245ureg->next_shader_processor = processor;2246}224722482249unsigned2250ureg_get_nr_outputs( const struct ureg_program *ureg )2251{2252if (!ureg)2253return 0;2254return ureg->nr_outputs;2255}22562257static void2258ureg_setup_clipdist_info(struct ureg_program *ureg,2259const struct shader_info *info)2260{2261if (info->clip_distance_array_size)2262ureg_property(ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED,2263info->clip_distance_array_size);2264if (info->cull_distance_array_size)2265ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED,2266info->cull_distance_array_size);2267}22682269static void2270ureg_setup_tess_ctrl_shader(struct ureg_program *ureg,2271const struct shader_info *info)2272{2273ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT,2274info->tess.tcs_vertices_out);2275}22762277static void2278ureg_setup_tess_eval_shader(struct ureg_program *ureg,2279const struct shader_info *info)2280{2281if (info->tess.primitive_mode == GL_ISOLINES)2282ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, GL_LINES);2283else2284ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE,2285info->tess.primitive_mode);22862287STATIC_ASSERT((TESS_SPACING_EQUAL + 1) % 3 == PIPE_TESS_SPACING_EQUAL);2288STATIC_ASSERT((TESS_SPACING_FRACTIONAL_ODD + 1) % 3 ==2289PIPE_TESS_SPACING_FRACTIONAL_ODD);2290STATIC_ASSERT((TESS_SPACING_FRACTIONAL_EVEN + 1) % 3 ==2291PIPE_TESS_SPACING_FRACTIONAL_EVEN);22922293ureg_property(ureg, TGSI_PROPERTY_TES_SPACING,2294(info->tess.spacing + 1) % 3);22952296ureg_property(ureg, TGSI_PROPERTY_TES_VERTEX_ORDER_CW,2297!info->tess.ccw);2298ureg_property(ureg, TGSI_PROPERTY_TES_POINT_MODE,2299info->tess.point_mode);2300}23012302static void2303ureg_setup_geometry_shader(struct ureg_program *ureg,2304const struct shader_info *info)2305{2306ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM,2307info->gs.input_primitive);2308ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM,2309info->gs.output_primitive);2310ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES,2311info->gs.vertices_out);2312ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS,2313info->gs.invocations);2314}23152316static void2317ureg_setup_fragment_shader(struct ureg_program *ureg,2318const struct shader_info *info)2319{2320if (info->fs.early_fragment_tests || info->fs.post_depth_coverage) {2321ureg_property(ureg, TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL, 1);23222323if (info->fs.post_depth_coverage)2324ureg_property(ureg, TGSI_PROPERTY_FS_POST_DEPTH_COVERAGE, 1);2325}23262327if (info->fs.depth_layout != FRAG_DEPTH_LAYOUT_NONE) {2328switch (info->fs.depth_layout) {2329case FRAG_DEPTH_LAYOUT_ANY:2330ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,2331TGSI_FS_DEPTH_LAYOUT_ANY);2332break;2333case FRAG_DEPTH_LAYOUT_GREATER:2334ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,2335TGSI_FS_DEPTH_LAYOUT_GREATER);2336break;2337case FRAG_DEPTH_LAYOUT_LESS:2338ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,2339TGSI_FS_DEPTH_LAYOUT_LESS);2340break;2341case FRAG_DEPTH_LAYOUT_UNCHANGED:2342ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,2343TGSI_FS_DEPTH_LAYOUT_UNCHANGED);2344break;2345default:2346assert(0);2347}2348}2349}23502351static void2352ureg_setup_compute_shader(struct ureg_program *ureg,2353const struct shader_info *info)2354{2355ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH,2356info->workgroup_size[0]);2357ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT,2358info->workgroup_size[1]);2359ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH,2360info->workgroup_size[2]);23612362if (info->shared_size)2363ureg_DECL_memory(ureg, TGSI_MEMORY_TYPE_SHARED);2364}23652366void2367ureg_setup_shader_info(struct ureg_program *ureg,2368const struct shader_info *info)2369{2370if (info->layer_viewport_relative)2371ureg_property(ureg, TGSI_PROPERTY_LAYER_VIEWPORT_RELATIVE, 1);23722373switch (info->stage) {2374case MESA_SHADER_VERTEX:2375ureg_setup_clipdist_info(ureg, info);2376ureg_set_next_shader_processor(ureg, pipe_shader_type_from_mesa(info->next_stage));2377break;2378case MESA_SHADER_TESS_CTRL:2379ureg_setup_tess_ctrl_shader(ureg, info);2380break;2381case MESA_SHADER_TESS_EVAL:2382ureg_setup_tess_eval_shader(ureg, info);2383ureg_setup_clipdist_info(ureg, info);2384ureg_set_next_shader_processor(ureg, pipe_shader_type_from_mesa(info->next_stage));2385break;2386case MESA_SHADER_GEOMETRY:2387ureg_setup_geometry_shader(ureg, info);2388ureg_setup_clipdist_info(ureg, info);2389break;2390case MESA_SHADER_FRAGMENT:2391ureg_setup_fragment_shader(ureg, info);2392break;2393case MESA_SHADER_COMPUTE:2394ureg_setup_compute_shader(ureg, info);2395break;2396default:2397break;2398}2399}240024012402void ureg_destroy( struct ureg_program *ureg )2403{2404unsigned i;24052406for (i = 0; i < ARRAY_SIZE(ureg->domain); i++) {2407if (ureg->domain[i].tokens &&2408ureg->domain[i].tokens != error_tokens)2409FREE(ureg->domain[i].tokens);2410}24112412util_bitmask_destroy(ureg->free_temps);2413util_bitmask_destroy(ureg->local_temps);2414util_bitmask_destroy(ureg->decl_temps);24152416FREE(ureg);2417}241824192420