1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009-2010 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "pipe/p_screen.h" 30bf215546Sopenharmony_ci#include "pipe/p_context.h" 31bf215546Sopenharmony_ci#include "pipe/p_state.h" 32bf215546Sopenharmony_ci#include "tgsi/tgsi_ureg.h" 33bf215546Sopenharmony_ci#include "tgsi/tgsi_build.h" 34bf215546Sopenharmony_ci#include "tgsi/tgsi_from_mesa.h" 35bf215546Sopenharmony_ci#include "tgsi/tgsi_info.h" 36bf215546Sopenharmony_ci#include "tgsi/tgsi_dump.h" 37bf215546Sopenharmony_ci#include "tgsi/tgsi_sanity.h" 38bf215546Sopenharmony_ci#include "util/u_debug.h" 39bf215546Sopenharmony_ci#include "util/u_inlines.h" 40bf215546Sopenharmony_ci#include "util/u_memory.h" 41bf215546Sopenharmony_ci#include "util/u_math.h" 42bf215546Sopenharmony_ci#include "util/u_prim.h" 43bf215546Sopenharmony_ci#include "util/u_bitmask.h" 44bf215546Sopenharmony_ci#include "GL/gl.h" 45bf215546Sopenharmony_ci#include "compiler/shader_info.h" 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ciunion tgsi_any_token { 48bf215546Sopenharmony_ci struct tgsi_header header; 49bf215546Sopenharmony_ci struct tgsi_processor processor; 50bf215546Sopenharmony_ci struct tgsi_token token; 51bf215546Sopenharmony_ci struct tgsi_property prop; 52bf215546Sopenharmony_ci struct tgsi_property_data prop_data; 53bf215546Sopenharmony_ci struct tgsi_declaration decl; 54bf215546Sopenharmony_ci struct tgsi_declaration_range decl_range; 55bf215546Sopenharmony_ci struct tgsi_declaration_dimension decl_dim; 56bf215546Sopenharmony_ci struct tgsi_declaration_interp decl_interp; 57bf215546Sopenharmony_ci struct tgsi_declaration_image decl_image; 58bf215546Sopenharmony_ci struct tgsi_declaration_semantic decl_semantic; 59bf215546Sopenharmony_ci struct tgsi_declaration_sampler_view decl_sampler_view; 60bf215546Sopenharmony_ci struct tgsi_declaration_array array; 61bf215546Sopenharmony_ci struct tgsi_immediate imm; 62bf215546Sopenharmony_ci union tgsi_immediate_data imm_data; 63bf215546Sopenharmony_ci struct tgsi_instruction insn; 64bf215546Sopenharmony_ci struct tgsi_instruction_label insn_label; 65bf215546Sopenharmony_ci struct tgsi_instruction_texture insn_texture; 66bf215546Sopenharmony_ci struct tgsi_instruction_memory insn_memory; 67bf215546Sopenharmony_ci struct tgsi_texture_offset insn_texture_offset; 68bf215546Sopenharmony_ci struct tgsi_src_register src; 69bf215546Sopenharmony_ci struct tgsi_ind_register ind; 70bf215546Sopenharmony_ci struct tgsi_dimension dim; 71bf215546Sopenharmony_ci struct tgsi_dst_register dst; 72bf215546Sopenharmony_ci unsigned value; 73bf215546Sopenharmony_ci}; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_cistruct ureg_tokens { 77bf215546Sopenharmony_ci union tgsi_any_token *tokens; 78bf215546Sopenharmony_ci unsigned size; 79bf215546Sopenharmony_ci unsigned order; 80bf215546Sopenharmony_ci unsigned count; 81bf215546Sopenharmony_ci}; 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci#define UREG_MAX_INPUT (4 * PIPE_MAX_SHADER_INPUTS) 84bf215546Sopenharmony_ci#define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS 85bf215546Sopenharmony_ci#define UREG_MAX_OUTPUT (4 * PIPE_MAX_SHADER_OUTPUTS) 86bf215546Sopenharmony_ci#define UREG_MAX_CONSTANT_RANGE 32 87bf215546Sopenharmony_ci#define UREG_MAX_HW_ATOMIC_RANGE 32 88bf215546Sopenharmony_ci#define UREG_MAX_IMMEDIATE 4096 89bf215546Sopenharmony_ci#define UREG_MAX_ADDR 3 90bf215546Sopenharmony_ci#define UREG_MAX_ARRAY_TEMPS 256 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_cistruct const_decl { 93bf215546Sopenharmony_ci struct { 94bf215546Sopenharmony_ci unsigned first; 95bf215546Sopenharmony_ci unsigned last; 96bf215546Sopenharmony_ci } constant_range[UREG_MAX_CONSTANT_RANGE]; 97bf215546Sopenharmony_ci unsigned nr_constant_ranges; 98bf215546Sopenharmony_ci}; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_cistruct hw_atomic_decl { 101bf215546Sopenharmony_ci struct hw_atomic_decl_range { 102bf215546Sopenharmony_ci unsigned first; 103bf215546Sopenharmony_ci unsigned last; 104bf215546Sopenharmony_ci unsigned array_id; 105bf215546Sopenharmony_ci } hw_atomic_range[UREG_MAX_HW_ATOMIC_RANGE]; 106bf215546Sopenharmony_ci unsigned nr_hw_atomic_ranges; 107bf215546Sopenharmony_ci}; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci#define DOMAIN_DECL 0 110bf215546Sopenharmony_ci#define DOMAIN_INSN 1 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_cistruct ureg_program 113bf215546Sopenharmony_ci{ 114bf215546Sopenharmony_ci enum pipe_shader_type processor; 115bf215546Sopenharmony_ci bool supports_any_inout_decl_range; 116bf215546Sopenharmony_ci int next_shader_processor; 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci struct ureg_input_decl { 119bf215546Sopenharmony_ci enum tgsi_semantic semantic_name; 120bf215546Sopenharmony_ci unsigned semantic_index; 121bf215546Sopenharmony_ci enum tgsi_interpolate_mode interp; 122bf215546Sopenharmony_ci unsigned char usage_mask; 123bf215546Sopenharmony_ci enum tgsi_interpolate_loc interp_location; 124bf215546Sopenharmony_ci unsigned first; 125bf215546Sopenharmony_ci unsigned last; 126bf215546Sopenharmony_ci unsigned array_id; 127bf215546Sopenharmony_ci } input[UREG_MAX_INPUT]; 128bf215546Sopenharmony_ci unsigned nr_inputs, nr_input_regs; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci unsigned vs_inputs[PIPE_MAX_ATTRIBS/32]; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci struct { 133bf215546Sopenharmony_ci enum tgsi_semantic semantic_name; 134bf215546Sopenharmony_ci unsigned semantic_index; 135bf215546Sopenharmony_ci } system_value[UREG_MAX_SYSTEM_VALUE]; 136bf215546Sopenharmony_ci unsigned nr_system_values; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci struct ureg_output_decl { 139bf215546Sopenharmony_ci enum tgsi_semantic semantic_name; 140bf215546Sopenharmony_ci unsigned semantic_index; 141bf215546Sopenharmony_ci unsigned streams; 142bf215546Sopenharmony_ci unsigned usage_mask; /* = TGSI_WRITEMASK_* */ 143bf215546Sopenharmony_ci unsigned first; 144bf215546Sopenharmony_ci unsigned last; 145bf215546Sopenharmony_ci unsigned array_id; 146bf215546Sopenharmony_ci boolean invariant; 147bf215546Sopenharmony_ci } output[UREG_MAX_OUTPUT]; 148bf215546Sopenharmony_ci unsigned nr_outputs, nr_output_regs; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci struct { 151bf215546Sopenharmony_ci union { 152bf215546Sopenharmony_ci float f[4]; 153bf215546Sopenharmony_ci unsigned u[4]; 154bf215546Sopenharmony_ci int i[4]; 155bf215546Sopenharmony_ci } value; 156bf215546Sopenharmony_ci unsigned nr; 157bf215546Sopenharmony_ci unsigned type; 158bf215546Sopenharmony_ci } immediate[UREG_MAX_IMMEDIATE]; 159bf215546Sopenharmony_ci unsigned nr_immediates; 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci struct ureg_src sampler[PIPE_MAX_SAMPLERS]; 162bf215546Sopenharmony_ci unsigned nr_samplers; 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci struct { 165bf215546Sopenharmony_ci unsigned index; 166bf215546Sopenharmony_ci enum tgsi_texture_type target; 167bf215546Sopenharmony_ci enum tgsi_return_type return_type_x; 168bf215546Sopenharmony_ci enum tgsi_return_type return_type_y; 169bf215546Sopenharmony_ci enum tgsi_return_type return_type_z; 170bf215546Sopenharmony_ci enum tgsi_return_type return_type_w; 171bf215546Sopenharmony_ci } sampler_view[PIPE_MAX_SHADER_SAMPLER_VIEWS]; 172bf215546Sopenharmony_ci unsigned nr_sampler_views; 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci struct { 175bf215546Sopenharmony_ci unsigned index; 176bf215546Sopenharmony_ci enum tgsi_texture_type target; 177bf215546Sopenharmony_ci enum pipe_format format; 178bf215546Sopenharmony_ci boolean wr; 179bf215546Sopenharmony_ci boolean raw; 180bf215546Sopenharmony_ci } image[PIPE_MAX_SHADER_IMAGES]; 181bf215546Sopenharmony_ci unsigned nr_images; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci struct { 184bf215546Sopenharmony_ci unsigned index; 185bf215546Sopenharmony_ci bool atomic; 186bf215546Sopenharmony_ci } buffer[PIPE_MAX_SHADER_BUFFERS]; 187bf215546Sopenharmony_ci unsigned nr_buffers; 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci struct util_bitmask *free_temps; 190bf215546Sopenharmony_ci struct util_bitmask *local_temps; 191bf215546Sopenharmony_ci struct util_bitmask *decl_temps; 192bf215546Sopenharmony_ci unsigned nr_temps; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci unsigned array_temps[UREG_MAX_ARRAY_TEMPS]; 195bf215546Sopenharmony_ci unsigned nr_array_temps; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci struct const_decl const_decls[PIPE_MAX_CONSTANT_BUFFERS]; 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci struct hw_atomic_decl hw_atomic_decls[PIPE_MAX_HW_ATOMIC_BUFFERS]; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci unsigned properties[TGSI_PROPERTY_COUNT]; 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci unsigned nr_addrs; 204bf215546Sopenharmony_ci unsigned nr_instructions; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci struct ureg_tokens domain[2]; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci bool use_memory[TGSI_MEMORY_TYPE_COUNT]; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci bool precise; 211bf215546Sopenharmony_ci}; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_cistatic union tgsi_any_token error_tokens[32]; 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_cistatic void tokens_error( struct ureg_tokens *tokens ) 216bf215546Sopenharmony_ci{ 217bf215546Sopenharmony_ci if (tokens->tokens && tokens->tokens != error_tokens) 218bf215546Sopenharmony_ci FREE(tokens->tokens); 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci tokens->tokens = error_tokens; 221bf215546Sopenharmony_ci tokens->size = ARRAY_SIZE(error_tokens); 222bf215546Sopenharmony_ci tokens->count = 0; 223bf215546Sopenharmony_ci} 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_cistatic void tokens_expand( struct ureg_tokens *tokens, 227bf215546Sopenharmony_ci unsigned count ) 228bf215546Sopenharmony_ci{ 229bf215546Sopenharmony_ci unsigned old_size = tokens->size * sizeof(unsigned); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci if (tokens->tokens == error_tokens) { 232bf215546Sopenharmony_ci return; 233bf215546Sopenharmony_ci } 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci while (tokens->count + count > tokens->size) { 236bf215546Sopenharmony_ci tokens->size = (1 << ++tokens->order); 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci tokens->tokens = REALLOC(tokens->tokens, 240bf215546Sopenharmony_ci old_size, 241bf215546Sopenharmony_ci tokens->size * sizeof(unsigned)); 242bf215546Sopenharmony_ci if (tokens->tokens == NULL) { 243bf215546Sopenharmony_ci tokens_error(tokens); 244bf215546Sopenharmony_ci } 245bf215546Sopenharmony_ci} 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_cistatic void set_bad( struct ureg_program *ureg ) 248bf215546Sopenharmony_ci{ 249bf215546Sopenharmony_ci tokens_error(&ureg->domain[0]); 250bf215546Sopenharmony_ci} 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_cistatic union tgsi_any_token *get_tokens( struct ureg_program *ureg, 255bf215546Sopenharmony_ci unsigned domain, 256bf215546Sopenharmony_ci unsigned count ) 257bf215546Sopenharmony_ci{ 258bf215546Sopenharmony_ci struct ureg_tokens *tokens = &ureg->domain[domain]; 259bf215546Sopenharmony_ci union tgsi_any_token *result; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci if (tokens->count + count > tokens->size) 262bf215546Sopenharmony_ci tokens_expand(tokens, count); 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci result = &tokens->tokens[tokens->count]; 265bf215546Sopenharmony_ci tokens->count += count; 266bf215546Sopenharmony_ci return result; 267bf215546Sopenharmony_ci} 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_cistatic union tgsi_any_token *retrieve_token( struct ureg_program *ureg, 271bf215546Sopenharmony_ci unsigned domain, 272bf215546Sopenharmony_ci unsigned nr ) 273bf215546Sopenharmony_ci{ 274bf215546Sopenharmony_ci if (ureg->domain[domain].tokens == error_tokens) 275bf215546Sopenharmony_ci return &error_tokens[0]; 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci return &ureg->domain[domain].tokens[nr]; 278bf215546Sopenharmony_ci} 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_civoid 282bf215546Sopenharmony_ciureg_property(struct ureg_program *ureg, unsigned name, unsigned value) 283bf215546Sopenharmony_ci{ 284bf215546Sopenharmony_ci assert(name < ARRAY_SIZE(ureg->properties)); 285bf215546Sopenharmony_ci ureg->properties[name] = value; 286bf215546Sopenharmony_ci} 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_cistruct ureg_src 289bf215546Sopenharmony_ciureg_DECL_fs_input_centroid_layout(struct ureg_program *ureg, 290bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 291bf215546Sopenharmony_ci unsigned semantic_index, 292bf215546Sopenharmony_ci enum tgsi_interpolate_mode interp_mode, 293bf215546Sopenharmony_ci enum tgsi_interpolate_loc interp_location, 294bf215546Sopenharmony_ci unsigned index, 295bf215546Sopenharmony_ci unsigned usage_mask, 296bf215546Sopenharmony_ci unsigned array_id, 297bf215546Sopenharmony_ci unsigned array_size) 298bf215546Sopenharmony_ci{ 299bf215546Sopenharmony_ci unsigned i; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci assert(usage_mask != 0); 302bf215546Sopenharmony_ci assert(usage_mask <= TGSI_WRITEMASK_XYZW); 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_inputs; i++) { 305bf215546Sopenharmony_ci if (ureg->input[i].semantic_name == semantic_name && 306bf215546Sopenharmony_ci ureg->input[i].semantic_index == semantic_index) { 307bf215546Sopenharmony_ci assert(ureg->input[i].interp == interp_mode); 308bf215546Sopenharmony_ci assert(ureg->input[i].interp_location == interp_location); 309bf215546Sopenharmony_ci if (ureg->input[i].array_id == array_id) { 310bf215546Sopenharmony_ci ureg->input[i].usage_mask |= usage_mask; 311bf215546Sopenharmony_ci ureg->input[i].last = MAX2(ureg->input[i].last, ureg->input[i].first + array_size - 1); 312bf215546Sopenharmony_ci ureg->nr_input_regs = MAX2(ureg->nr_input_regs, ureg->input[i].last + 1); 313bf215546Sopenharmony_ci goto out; 314bf215546Sopenharmony_ci } 315bf215546Sopenharmony_ci assert((ureg->input[i].usage_mask & usage_mask) == 0); 316bf215546Sopenharmony_ci } 317bf215546Sopenharmony_ci } 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci if (ureg->nr_inputs < UREG_MAX_INPUT) { 320bf215546Sopenharmony_ci assert(array_size >= 1); 321bf215546Sopenharmony_ci ureg->input[i].semantic_name = semantic_name; 322bf215546Sopenharmony_ci ureg->input[i].semantic_index = semantic_index; 323bf215546Sopenharmony_ci ureg->input[i].interp = interp_mode; 324bf215546Sopenharmony_ci ureg->input[i].interp_location = interp_location; 325bf215546Sopenharmony_ci ureg->input[i].first = index; 326bf215546Sopenharmony_ci ureg->input[i].last = index + array_size - 1; 327bf215546Sopenharmony_ci ureg->input[i].array_id = array_id; 328bf215546Sopenharmony_ci ureg->input[i].usage_mask = usage_mask; 329bf215546Sopenharmony_ci ureg->nr_input_regs = MAX2(ureg->nr_input_regs, index + array_size); 330bf215546Sopenharmony_ci ureg->nr_inputs++; 331bf215546Sopenharmony_ci } else { 332bf215546Sopenharmony_ci set_bad(ureg); 333bf215546Sopenharmony_ci } 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ciout: 336bf215546Sopenharmony_ci return ureg_src_array_register(TGSI_FILE_INPUT, ureg->input[i].first, 337bf215546Sopenharmony_ci array_id); 338bf215546Sopenharmony_ci} 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_cistruct ureg_src 341bf215546Sopenharmony_ciureg_DECL_fs_input_centroid(struct ureg_program *ureg, 342bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 343bf215546Sopenharmony_ci unsigned semantic_index, 344bf215546Sopenharmony_ci enum tgsi_interpolate_mode interp_mode, 345bf215546Sopenharmony_ci enum tgsi_interpolate_loc interp_location, 346bf215546Sopenharmony_ci unsigned array_id, 347bf215546Sopenharmony_ci unsigned array_size) 348bf215546Sopenharmony_ci{ 349bf215546Sopenharmony_ci return ureg_DECL_fs_input_centroid_layout(ureg, 350bf215546Sopenharmony_ci semantic_name, semantic_index, interp_mode, 351bf215546Sopenharmony_ci interp_location, 352bf215546Sopenharmony_ci ureg->nr_input_regs, TGSI_WRITEMASK_XYZW, array_id, array_size); 353bf215546Sopenharmony_ci} 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_cistruct ureg_src 357bf215546Sopenharmony_ciureg_DECL_vs_input( struct ureg_program *ureg, 358bf215546Sopenharmony_ci unsigned index ) 359bf215546Sopenharmony_ci{ 360bf215546Sopenharmony_ci assert(ureg->processor == PIPE_SHADER_VERTEX); 361bf215546Sopenharmony_ci assert(index / 32 < ARRAY_SIZE(ureg->vs_inputs)); 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci ureg->vs_inputs[index/32] |= 1 << (index % 32); 364bf215546Sopenharmony_ci return ureg_src_register( TGSI_FILE_INPUT, index ); 365bf215546Sopenharmony_ci} 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_cistruct ureg_src 369bf215546Sopenharmony_ciureg_DECL_input_layout(struct ureg_program *ureg, 370bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 371bf215546Sopenharmony_ci unsigned semantic_index, 372bf215546Sopenharmony_ci unsigned index, 373bf215546Sopenharmony_ci unsigned usage_mask, 374bf215546Sopenharmony_ci unsigned array_id, 375bf215546Sopenharmony_ci unsigned array_size) 376bf215546Sopenharmony_ci{ 377bf215546Sopenharmony_ci return ureg_DECL_fs_input_centroid_layout(ureg, 378bf215546Sopenharmony_ci semantic_name, semantic_index, 379bf215546Sopenharmony_ci TGSI_INTERPOLATE_CONSTANT, TGSI_INTERPOLATE_LOC_CENTER, 380bf215546Sopenharmony_ci index, usage_mask, array_id, array_size); 381bf215546Sopenharmony_ci} 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_cistruct ureg_src 385bf215546Sopenharmony_ciureg_DECL_input(struct ureg_program *ureg, 386bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 387bf215546Sopenharmony_ci unsigned semantic_index, 388bf215546Sopenharmony_ci unsigned array_id, 389bf215546Sopenharmony_ci unsigned array_size) 390bf215546Sopenharmony_ci{ 391bf215546Sopenharmony_ci return ureg_DECL_fs_input_centroid(ureg, semantic_name, semantic_index, 392bf215546Sopenharmony_ci TGSI_INTERPOLATE_CONSTANT, 393bf215546Sopenharmony_ci TGSI_INTERPOLATE_LOC_CENTER, 394bf215546Sopenharmony_ci array_id, array_size); 395bf215546Sopenharmony_ci} 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_cistruct ureg_src 399bf215546Sopenharmony_ciureg_DECL_system_value(struct ureg_program *ureg, 400bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 401bf215546Sopenharmony_ci unsigned semantic_index) 402bf215546Sopenharmony_ci{ 403bf215546Sopenharmony_ci unsigned i; 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_system_values; i++) { 406bf215546Sopenharmony_ci if (ureg->system_value[i].semantic_name == semantic_name && 407bf215546Sopenharmony_ci ureg->system_value[i].semantic_index == semantic_index) { 408bf215546Sopenharmony_ci goto out; 409bf215546Sopenharmony_ci } 410bf215546Sopenharmony_ci } 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci if (ureg->nr_system_values < UREG_MAX_SYSTEM_VALUE) { 413bf215546Sopenharmony_ci ureg->system_value[ureg->nr_system_values].semantic_name = semantic_name; 414bf215546Sopenharmony_ci ureg->system_value[ureg->nr_system_values].semantic_index = semantic_index; 415bf215546Sopenharmony_ci i = ureg->nr_system_values; 416bf215546Sopenharmony_ci ureg->nr_system_values++; 417bf215546Sopenharmony_ci } else { 418bf215546Sopenharmony_ci set_bad(ureg); 419bf215546Sopenharmony_ci } 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ciout: 422bf215546Sopenharmony_ci return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, i); 423bf215546Sopenharmony_ci} 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_cistruct ureg_dst 427bf215546Sopenharmony_ciureg_DECL_output_layout(struct ureg_program *ureg, 428bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 429bf215546Sopenharmony_ci unsigned semantic_index, 430bf215546Sopenharmony_ci unsigned streams, 431bf215546Sopenharmony_ci unsigned index, 432bf215546Sopenharmony_ci unsigned usage_mask, 433bf215546Sopenharmony_ci unsigned array_id, 434bf215546Sopenharmony_ci unsigned array_size, 435bf215546Sopenharmony_ci boolean invariant) 436bf215546Sopenharmony_ci{ 437bf215546Sopenharmony_ci unsigned i; 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci assert(usage_mask != 0); 440bf215546Sopenharmony_ci assert(!(streams & 0x03) || (usage_mask & 1)); 441bf215546Sopenharmony_ci assert(!(streams & 0x0c) || (usage_mask & 2)); 442bf215546Sopenharmony_ci assert(!(streams & 0x30) || (usage_mask & 4)); 443bf215546Sopenharmony_ci assert(!(streams & 0xc0) || (usage_mask & 8)); 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_outputs; i++) { 446bf215546Sopenharmony_ci if (ureg->output[i].semantic_name == semantic_name && 447bf215546Sopenharmony_ci ureg->output[i].semantic_index == semantic_index) { 448bf215546Sopenharmony_ci if (ureg->output[i].array_id == array_id) { 449bf215546Sopenharmony_ci ureg->output[i].usage_mask |= usage_mask; 450bf215546Sopenharmony_ci ureg->output[i].last = MAX2(ureg->output[i].last, ureg->output[i].first + array_size - 1); 451bf215546Sopenharmony_ci ureg->nr_output_regs = MAX2(ureg->nr_output_regs, ureg->output[i].last + 1); 452bf215546Sopenharmony_ci goto out; 453bf215546Sopenharmony_ci } 454bf215546Sopenharmony_ci assert((ureg->output[i].usage_mask & usage_mask) == 0); 455bf215546Sopenharmony_ci } 456bf215546Sopenharmony_ci } 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci if (ureg->nr_outputs < UREG_MAX_OUTPUT) { 459bf215546Sopenharmony_ci ureg->output[i].semantic_name = semantic_name; 460bf215546Sopenharmony_ci ureg->output[i].semantic_index = semantic_index; 461bf215546Sopenharmony_ci ureg->output[i].usage_mask = usage_mask; 462bf215546Sopenharmony_ci ureg->output[i].first = index; 463bf215546Sopenharmony_ci ureg->output[i].last = index + array_size - 1; 464bf215546Sopenharmony_ci ureg->output[i].array_id = array_id; 465bf215546Sopenharmony_ci ureg->output[i].invariant = invariant; 466bf215546Sopenharmony_ci ureg->nr_output_regs = MAX2(ureg->nr_output_regs, index + array_size); 467bf215546Sopenharmony_ci ureg->nr_outputs++; 468bf215546Sopenharmony_ci } 469bf215546Sopenharmony_ci else { 470bf215546Sopenharmony_ci set_bad( ureg ); 471bf215546Sopenharmony_ci i = 0; 472bf215546Sopenharmony_ci } 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ciout: 475bf215546Sopenharmony_ci ureg->output[i].streams |= streams; 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci return ureg_dst_array_register(TGSI_FILE_OUTPUT, ureg->output[i].first, 478bf215546Sopenharmony_ci array_id); 479bf215546Sopenharmony_ci} 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_cistruct ureg_dst 483bf215546Sopenharmony_ciureg_DECL_output_masked(struct ureg_program *ureg, 484bf215546Sopenharmony_ci unsigned name, 485bf215546Sopenharmony_ci unsigned index, 486bf215546Sopenharmony_ci unsigned usage_mask, 487bf215546Sopenharmony_ci unsigned array_id, 488bf215546Sopenharmony_ci unsigned array_size) 489bf215546Sopenharmony_ci{ 490bf215546Sopenharmony_ci return ureg_DECL_output_layout(ureg, name, index, 0, 491bf215546Sopenharmony_ci ureg->nr_output_regs, usage_mask, array_id, 492bf215546Sopenharmony_ci array_size, FALSE); 493bf215546Sopenharmony_ci} 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_cistruct ureg_dst 497bf215546Sopenharmony_ciureg_DECL_output(struct ureg_program *ureg, 498bf215546Sopenharmony_ci enum tgsi_semantic name, 499bf215546Sopenharmony_ci unsigned index) 500bf215546Sopenharmony_ci{ 501bf215546Sopenharmony_ci return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW, 502bf215546Sopenharmony_ci 0, 1); 503bf215546Sopenharmony_ci} 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_cistruct ureg_dst 506bf215546Sopenharmony_ciureg_DECL_output_array(struct ureg_program *ureg, 507bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 508bf215546Sopenharmony_ci unsigned semantic_index, 509bf215546Sopenharmony_ci unsigned array_id, 510bf215546Sopenharmony_ci unsigned array_size) 511bf215546Sopenharmony_ci{ 512bf215546Sopenharmony_ci return ureg_DECL_output_masked(ureg, semantic_name, semantic_index, 513bf215546Sopenharmony_ci TGSI_WRITEMASK_XYZW, 514bf215546Sopenharmony_ci array_id, array_size); 515bf215546Sopenharmony_ci} 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci/* Returns a new constant register. Keep track of which have been 519bf215546Sopenharmony_ci * referred to so that we can emit decls later. 520bf215546Sopenharmony_ci * 521bf215546Sopenharmony_ci * Constant operands declared with this function must be addressed 522bf215546Sopenharmony_ci * with a two-dimensional index. 523bf215546Sopenharmony_ci * 524bf215546Sopenharmony_ci * There is nothing in this code to bind this constant to any tracked 525bf215546Sopenharmony_ci * value or manage any constant_buffer contents -- that's the 526bf215546Sopenharmony_ci * resposibility of the calling code. 527bf215546Sopenharmony_ci */ 528bf215546Sopenharmony_civoid 529bf215546Sopenharmony_ciureg_DECL_constant2D(struct ureg_program *ureg, 530bf215546Sopenharmony_ci unsigned first, 531bf215546Sopenharmony_ci unsigned last, 532bf215546Sopenharmony_ci unsigned index2D) 533bf215546Sopenharmony_ci{ 534bf215546Sopenharmony_ci struct const_decl *decl = &ureg->const_decls[index2D]; 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci assert(index2D < PIPE_MAX_CONSTANT_BUFFERS); 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) { 539bf215546Sopenharmony_ci uint i = decl->nr_constant_ranges++; 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci decl->constant_range[i].first = first; 542bf215546Sopenharmony_ci decl->constant_range[i].last = last; 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci} 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci/* A one-dimensional, deprecated version of ureg_DECL_constant2D(). 548bf215546Sopenharmony_ci * 549bf215546Sopenharmony_ci * Constant operands declared with this function must be addressed 550bf215546Sopenharmony_ci * with a one-dimensional index. 551bf215546Sopenharmony_ci */ 552bf215546Sopenharmony_cistruct ureg_src 553bf215546Sopenharmony_ciureg_DECL_constant(struct ureg_program *ureg, 554bf215546Sopenharmony_ci unsigned index) 555bf215546Sopenharmony_ci{ 556bf215546Sopenharmony_ci struct const_decl *decl = &ureg->const_decls[0]; 557bf215546Sopenharmony_ci unsigned minconst = index, maxconst = index; 558bf215546Sopenharmony_ci unsigned i; 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci /* Inside existing range? 561bf215546Sopenharmony_ci */ 562bf215546Sopenharmony_ci for (i = 0; i < decl->nr_constant_ranges; i++) { 563bf215546Sopenharmony_ci if (decl->constant_range[i].first <= index && 564bf215546Sopenharmony_ci decl->constant_range[i].last >= index) { 565bf215546Sopenharmony_ci goto out; 566bf215546Sopenharmony_ci } 567bf215546Sopenharmony_ci } 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci /* Extend existing range? 570bf215546Sopenharmony_ci */ 571bf215546Sopenharmony_ci for (i = 0; i < decl->nr_constant_ranges; i++) { 572bf215546Sopenharmony_ci if (decl->constant_range[i].last == index - 1) { 573bf215546Sopenharmony_ci decl->constant_range[i].last = index; 574bf215546Sopenharmony_ci goto out; 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_ci if (decl->constant_range[i].first == index + 1) { 578bf215546Sopenharmony_ci decl->constant_range[i].first = index; 579bf215546Sopenharmony_ci goto out; 580bf215546Sopenharmony_ci } 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci minconst = MIN2(minconst, decl->constant_range[i].first); 583bf215546Sopenharmony_ci maxconst = MAX2(maxconst, decl->constant_range[i].last); 584bf215546Sopenharmony_ci } 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci /* Create new range? 587bf215546Sopenharmony_ci */ 588bf215546Sopenharmony_ci if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) { 589bf215546Sopenharmony_ci i = decl->nr_constant_ranges++; 590bf215546Sopenharmony_ci decl->constant_range[i].first = index; 591bf215546Sopenharmony_ci decl->constant_range[i].last = index; 592bf215546Sopenharmony_ci goto out; 593bf215546Sopenharmony_ci } 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci /* Collapse all ranges down to one: 596bf215546Sopenharmony_ci */ 597bf215546Sopenharmony_ci i = 0; 598bf215546Sopenharmony_ci decl->constant_range[0].first = minconst; 599bf215546Sopenharmony_ci decl->constant_range[0].last = maxconst; 600bf215546Sopenharmony_ci decl->nr_constant_ranges = 1; 601bf215546Sopenharmony_ci 602bf215546Sopenharmony_ciout: 603bf215546Sopenharmony_ci assert(i < decl->nr_constant_ranges); 604bf215546Sopenharmony_ci assert(decl->constant_range[i].first <= index); 605bf215546Sopenharmony_ci assert(decl->constant_range[i].last >= index); 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci struct ureg_src src = ureg_src_register(TGSI_FILE_CONSTANT, index); 608bf215546Sopenharmony_ci return ureg_src_dimension(src, 0); 609bf215546Sopenharmony_ci} 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci/* Returns a new hw atomic register. Keep track of which have been 613bf215546Sopenharmony_ci * referred to so that we can emit decls later. 614bf215546Sopenharmony_ci */ 615bf215546Sopenharmony_civoid 616bf215546Sopenharmony_ciureg_DECL_hw_atomic(struct ureg_program *ureg, 617bf215546Sopenharmony_ci unsigned first, 618bf215546Sopenharmony_ci unsigned last, 619bf215546Sopenharmony_ci unsigned buffer_id, 620bf215546Sopenharmony_ci unsigned array_id) 621bf215546Sopenharmony_ci{ 622bf215546Sopenharmony_ci struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[buffer_id]; 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci if (decl->nr_hw_atomic_ranges < UREG_MAX_HW_ATOMIC_RANGE) { 625bf215546Sopenharmony_ci uint i = decl->nr_hw_atomic_ranges++; 626bf215546Sopenharmony_ci 627bf215546Sopenharmony_ci decl->hw_atomic_range[i].first = first; 628bf215546Sopenharmony_ci decl->hw_atomic_range[i].last = last; 629bf215546Sopenharmony_ci decl->hw_atomic_range[i].array_id = array_id; 630bf215546Sopenharmony_ci } else { 631bf215546Sopenharmony_ci set_bad(ureg); 632bf215546Sopenharmony_ci } 633bf215546Sopenharmony_ci} 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_cistatic struct ureg_dst alloc_temporary( struct ureg_program *ureg, 636bf215546Sopenharmony_ci boolean local ) 637bf215546Sopenharmony_ci{ 638bf215546Sopenharmony_ci unsigned i; 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ci /* Look for a released temporary. 641bf215546Sopenharmony_ci */ 642bf215546Sopenharmony_ci for (i = util_bitmask_get_first_index(ureg->free_temps); 643bf215546Sopenharmony_ci i != UTIL_BITMASK_INVALID_INDEX; 644bf215546Sopenharmony_ci i = util_bitmask_get_next_index(ureg->free_temps, i + 1)) { 645bf215546Sopenharmony_ci if (util_bitmask_get(ureg->local_temps, i) == local) 646bf215546Sopenharmony_ci break; 647bf215546Sopenharmony_ci } 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_ci /* Or allocate a new one. 650bf215546Sopenharmony_ci */ 651bf215546Sopenharmony_ci if (i == UTIL_BITMASK_INVALID_INDEX) { 652bf215546Sopenharmony_ci i = ureg->nr_temps++; 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci if (local) 655bf215546Sopenharmony_ci util_bitmask_set(ureg->local_temps, i); 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci /* Start a new declaration when the local flag changes */ 658bf215546Sopenharmony_ci if (!i || util_bitmask_get(ureg->local_temps, i - 1) != local) 659bf215546Sopenharmony_ci util_bitmask_set(ureg->decl_temps, i); 660bf215546Sopenharmony_ci } 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ci util_bitmask_clear(ureg->free_temps, i); 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_ci return ureg_dst_register( TGSI_FILE_TEMPORARY, i ); 665bf215546Sopenharmony_ci} 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_cistruct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg ) 668bf215546Sopenharmony_ci{ 669bf215546Sopenharmony_ci return alloc_temporary(ureg, FALSE); 670bf215546Sopenharmony_ci} 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_cistruct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg ) 673bf215546Sopenharmony_ci{ 674bf215546Sopenharmony_ci return alloc_temporary(ureg, TRUE); 675bf215546Sopenharmony_ci} 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_cistruct ureg_dst ureg_DECL_array_temporary( struct ureg_program *ureg, 678bf215546Sopenharmony_ci unsigned size, 679bf215546Sopenharmony_ci boolean local ) 680bf215546Sopenharmony_ci{ 681bf215546Sopenharmony_ci unsigned i = ureg->nr_temps; 682bf215546Sopenharmony_ci struct ureg_dst dst = ureg_dst_register( TGSI_FILE_TEMPORARY, i ); 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci if (local) 685bf215546Sopenharmony_ci util_bitmask_set(ureg->local_temps, i); 686bf215546Sopenharmony_ci 687bf215546Sopenharmony_ci /* Always start a new declaration at the start */ 688bf215546Sopenharmony_ci util_bitmask_set(ureg->decl_temps, i); 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci ureg->nr_temps += size; 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci /* and also at the end of the array */ 693bf215546Sopenharmony_ci util_bitmask_set(ureg->decl_temps, ureg->nr_temps); 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci if (ureg->nr_array_temps < UREG_MAX_ARRAY_TEMPS) { 696bf215546Sopenharmony_ci ureg->array_temps[ureg->nr_array_temps++] = i; 697bf215546Sopenharmony_ci dst.ArrayID = ureg->nr_array_temps; 698bf215546Sopenharmony_ci } 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_ci return dst; 701bf215546Sopenharmony_ci} 702bf215546Sopenharmony_ci 703bf215546Sopenharmony_civoid ureg_release_temporary( struct ureg_program *ureg, 704bf215546Sopenharmony_ci struct ureg_dst tmp ) 705bf215546Sopenharmony_ci{ 706bf215546Sopenharmony_ci if(tmp.File == TGSI_FILE_TEMPORARY) 707bf215546Sopenharmony_ci util_bitmask_set(ureg->free_temps, tmp.Index); 708bf215546Sopenharmony_ci} 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_ci 711bf215546Sopenharmony_ci/* Allocate a new address register. 712bf215546Sopenharmony_ci */ 713bf215546Sopenharmony_cistruct ureg_dst ureg_DECL_address( struct ureg_program *ureg ) 714bf215546Sopenharmony_ci{ 715bf215546Sopenharmony_ci if (ureg->nr_addrs < UREG_MAX_ADDR) 716bf215546Sopenharmony_ci return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ ); 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ci assert( 0 ); 719bf215546Sopenharmony_ci return ureg_dst_register( TGSI_FILE_ADDRESS, 0 ); 720bf215546Sopenharmony_ci} 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_ci/* Allocate a new sampler. 723bf215546Sopenharmony_ci */ 724bf215546Sopenharmony_cistruct ureg_src ureg_DECL_sampler( struct ureg_program *ureg, 725bf215546Sopenharmony_ci unsigned nr ) 726bf215546Sopenharmony_ci{ 727bf215546Sopenharmony_ci unsigned i; 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_samplers; i++) 730bf215546Sopenharmony_ci if (ureg->sampler[i].Index == (int)nr) 731bf215546Sopenharmony_ci return ureg->sampler[i]; 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_ci if (i < PIPE_MAX_SAMPLERS) { 734bf215546Sopenharmony_ci ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr ); 735bf215546Sopenharmony_ci ureg->nr_samplers++; 736bf215546Sopenharmony_ci return ureg->sampler[i]; 737bf215546Sopenharmony_ci } 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci assert( 0 ); 740bf215546Sopenharmony_ci return ureg->sampler[0]; 741bf215546Sopenharmony_ci} 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci/* 744bf215546Sopenharmony_ci * Allocate a new shader sampler view. 745bf215546Sopenharmony_ci */ 746bf215546Sopenharmony_cistruct ureg_src 747bf215546Sopenharmony_ciureg_DECL_sampler_view(struct ureg_program *ureg, 748bf215546Sopenharmony_ci unsigned index, 749bf215546Sopenharmony_ci enum tgsi_texture_type target, 750bf215546Sopenharmony_ci enum tgsi_return_type return_type_x, 751bf215546Sopenharmony_ci enum tgsi_return_type return_type_y, 752bf215546Sopenharmony_ci enum tgsi_return_type return_type_z, 753bf215546Sopenharmony_ci enum tgsi_return_type return_type_w) 754bf215546Sopenharmony_ci{ 755bf215546Sopenharmony_ci struct ureg_src reg = ureg_src_register(TGSI_FILE_SAMPLER_VIEW, index); 756bf215546Sopenharmony_ci uint i; 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_sampler_views; i++) { 759bf215546Sopenharmony_ci if (ureg->sampler_view[i].index == index) { 760bf215546Sopenharmony_ci return reg; 761bf215546Sopenharmony_ci } 762bf215546Sopenharmony_ci } 763bf215546Sopenharmony_ci 764bf215546Sopenharmony_ci if (i < PIPE_MAX_SHADER_SAMPLER_VIEWS) { 765bf215546Sopenharmony_ci ureg->sampler_view[i].index = index; 766bf215546Sopenharmony_ci ureg->sampler_view[i].target = target; 767bf215546Sopenharmony_ci ureg->sampler_view[i].return_type_x = return_type_x; 768bf215546Sopenharmony_ci ureg->sampler_view[i].return_type_y = return_type_y; 769bf215546Sopenharmony_ci ureg->sampler_view[i].return_type_z = return_type_z; 770bf215546Sopenharmony_ci ureg->sampler_view[i].return_type_w = return_type_w; 771bf215546Sopenharmony_ci ureg->nr_sampler_views++; 772bf215546Sopenharmony_ci return reg; 773bf215546Sopenharmony_ci } 774bf215546Sopenharmony_ci 775bf215546Sopenharmony_ci assert(0); 776bf215546Sopenharmony_ci return reg; 777bf215546Sopenharmony_ci} 778bf215546Sopenharmony_ci 779bf215546Sopenharmony_ci/* Allocate a new image. 780bf215546Sopenharmony_ci */ 781bf215546Sopenharmony_cistruct ureg_src 782bf215546Sopenharmony_ciureg_DECL_image(struct ureg_program *ureg, 783bf215546Sopenharmony_ci unsigned index, 784bf215546Sopenharmony_ci enum tgsi_texture_type target, 785bf215546Sopenharmony_ci enum pipe_format format, 786bf215546Sopenharmony_ci boolean wr, 787bf215546Sopenharmony_ci boolean raw) 788bf215546Sopenharmony_ci{ 789bf215546Sopenharmony_ci struct ureg_src reg = ureg_src_register(TGSI_FILE_IMAGE, index); 790bf215546Sopenharmony_ci unsigned i; 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_images; i++) 793bf215546Sopenharmony_ci if (ureg->image[i].index == index) 794bf215546Sopenharmony_ci return reg; 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci if (i < PIPE_MAX_SHADER_IMAGES) { 797bf215546Sopenharmony_ci ureg->image[i].index = index; 798bf215546Sopenharmony_ci ureg->image[i].target = target; 799bf215546Sopenharmony_ci ureg->image[i].wr = wr; 800bf215546Sopenharmony_ci ureg->image[i].raw = raw; 801bf215546Sopenharmony_ci ureg->image[i].format = format; 802bf215546Sopenharmony_ci ureg->nr_images++; 803bf215546Sopenharmony_ci return reg; 804bf215546Sopenharmony_ci } 805bf215546Sopenharmony_ci 806bf215546Sopenharmony_ci assert(0); 807bf215546Sopenharmony_ci return reg; 808bf215546Sopenharmony_ci} 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci/* Allocate a new buffer. 811bf215546Sopenharmony_ci */ 812bf215546Sopenharmony_cistruct ureg_src ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr, 813bf215546Sopenharmony_ci bool atomic) 814bf215546Sopenharmony_ci{ 815bf215546Sopenharmony_ci struct ureg_src reg = ureg_src_register(TGSI_FILE_BUFFER, nr); 816bf215546Sopenharmony_ci unsigned i; 817bf215546Sopenharmony_ci 818bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_buffers; i++) 819bf215546Sopenharmony_ci if (ureg->buffer[i].index == nr) 820bf215546Sopenharmony_ci return reg; 821bf215546Sopenharmony_ci 822bf215546Sopenharmony_ci if (i < PIPE_MAX_SHADER_BUFFERS) { 823bf215546Sopenharmony_ci ureg->buffer[i].index = nr; 824bf215546Sopenharmony_ci ureg->buffer[i].atomic = atomic; 825bf215546Sopenharmony_ci ureg->nr_buffers++; 826bf215546Sopenharmony_ci return reg; 827bf215546Sopenharmony_ci } 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_ci assert(0); 830bf215546Sopenharmony_ci return reg; 831bf215546Sopenharmony_ci} 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci/* Allocate a memory area. 834bf215546Sopenharmony_ci */ 835bf215546Sopenharmony_cistruct ureg_src ureg_DECL_memory(struct ureg_program *ureg, 836bf215546Sopenharmony_ci unsigned memory_type) 837bf215546Sopenharmony_ci{ 838bf215546Sopenharmony_ci struct ureg_src reg = ureg_src_register(TGSI_FILE_MEMORY, memory_type); 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_ci ureg->use_memory[memory_type] = true; 841bf215546Sopenharmony_ci return reg; 842bf215546Sopenharmony_ci} 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_cistatic int 845bf215546Sopenharmony_cimatch_or_expand_immediate64( const unsigned *v, 846bf215546Sopenharmony_ci unsigned nr, 847bf215546Sopenharmony_ci unsigned *v2, 848bf215546Sopenharmony_ci unsigned *pnr2, 849bf215546Sopenharmony_ci unsigned *swizzle ) 850bf215546Sopenharmony_ci{ 851bf215546Sopenharmony_ci unsigned nr2 = *pnr2; 852bf215546Sopenharmony_ci unsigned i, j; 853bf215546Sopenharmony_ci *swizzle = 0; 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci for (i = 0; i < nr; i += 2) { 856bf215546Sopenharmony_ci boolean found = FALSE; 857bf215546Sopenharmony_ci 858bf215546Sopenharmony_ci for (j = 0; j < nr2 && !found; j += 2) { 859bf215546Sopenharmony_ci if (v[i] == v2[j] && v[i + 1] == v2[j + 1]) { 860bf215546Sopenharmony_ci *swizzle |= (j << (i * 2)) | ((j + 1) << ((i + 1) * 2)); 861bf215546Sopenharmony_ci found = TRUE; 862bf215546Sopenharmony_ci } 863bf215546Sopenharmony_ci } 864bf215546Sopenharmony_ci if (!found) { 865bf215546Sopenharmony_ci if ((nr2) >= 4) { 866bf215546Sopenharmony_ci return FALSE; 867bf215546Sopenharmony_ci } 868bf215546Sopenharmony_ci 869bf215546Sopenharmony_ci v2[nr2] = v[i]; 870bf215546Sopenharmony_ci v2[nr2 + 1] = v[i + 1]; 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_ci *swizzle |= (nr2 << (i * 2)) | ((nr2 + 1) << ((i + 1) * 2)); 873bf215546Sopenharmony_ci nr2 += 2; 874bf215546Sopenharmony_ci } 875bf215546Sopenharmony_ci } 876bf215546Sopenharmony_ci 877bf215546Sopenharmony_ci /* Actually expand immediate only when fully succeeded. 878bf215546Sopenharmony_ci */ 879bf215546Sopenharmony_ci *pnr2 = nr2; 880bf215546Sopenharmony_ci return TRUE; 881bf215546Sopenharmony_ci} 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_cistatic int 884bf215546Sopenharmony_cimatch_or_expand_immediate( const unsigned *v, 885bf215546Sopenharmony_ci int type, 886bf215546Sopenharmony_ci unsigned nr, 887bf215546Sopenharmony_ci unsigned *v2, 888bf215546Sopenharmony_ci unsigned *pnr2, 889bf215546Sopenharmony_ci unsigned *swizzle ) 890bf215546Sopenharmony_ci{ 891bf215546Sopenharmony_ci unsigned nr2 = *pnr2; 892bf215546Sopenharmony_ci unsigned i, j; 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci if (type == TGSI_IMM_FLOAT64 || 895bf215546Sopenharmony_ci type == TGSI_IMM_UINT64 || 896bf215546Sopenharmony_ci type == TGSI_IMM_INT64) 897bf215546Sopenharmony_ci return match_or_expand_immediate64(v, nr, v2, pnr2, swizzle); 898bf215546Sopenharmony_ci 899bf215546Sopenharmony_ci *swizzle = 0; 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci for (i = 0; i < nr; i++) { 902bf215546Sopenharmony_ci boolean found = FALSE; 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci for (j = 0; j < nr2 && !found; j++) { 905bf215546Sopenharmony_ci if (v[i] == v2[j]) { 906bf215546Sopenharmony_ci *swizzle |= j << (i * 2); 907bf215546Sopenharmony_ci found = TRUE; 908bf215546Sopenharmony_ci } 909bf215546Sopenharmony_ci } 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_ci if (!found) { 912bf215546Sopenharmony_ci if (nr2 >= 4) { 913bf215546Sopenharmony_ci return FALSE; 914bf215546Sopenharmony_ci } 915bf215546Sopenharmony_ci 916bf215546Sopenharmony_ci v2[nr2] = v[i]; 917bf215546Sopenharmony_ci *swizzle |= nr2 << (i * 2); 918bf215546Sopenharmony_ci nr2++; 919bf215546Sopenharmony_ci } 920bf215546Sopenharmony_ci } 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci /* Actually expand immediate only when fully succeeded. 923bf215546Sopenharmony_ci */ 924bf215546Sopenharmony_ci *pnr2 = nr2; 925bf215546Sopenharmony_ci return TRUE; 926bf215546Sopenharmony_ci} 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_cistatic struct ureg_src 930bf215546Sopenharmony_cidecl_immediate( struct ureg_program *ureg, 931bf215546Sopenharmony_ci const unsigned *v, 932bf215546Sopenharmony_ci unsigned nr, 933bf215546Sopenharmony_ci unsigned type ) 934bf215546Sopenharmony_ci{ 935bf215546Sopenharmony_ci unsigned i, j; 936bf215546Sopenharmony_ci unsigned swizzle = 0; 937bf215546Sopenharmony_ci 938bf215546Sopenharmony_ci /* Could do a first pass where we examine all existing immediates 939bf215546Sopenharmony_ci * without expanding. 940bf215546Sopenharmony_ci */ 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_immediates; i++) { 943bf215546Sopenharmony_ci if (ureg->immediate[i].type != type) { 944bf215546Sopenharmony_ci continue; 945bf215546Sopenharmony_ci } 946bf215546Sopenharmony_ci if (match_or_expand_immediate(v, 947bf215546Sopenharmony_ci type, 948bf215546Sopenharmony_ci nr, 949bf215546Sopenharmony_ci ureg->immediate[i].value.u, 950bf215546Sopenharmony_ci &ureg->immediate[i].nr, 951bf215546Sopenharmony_ci &swizzle)) { 952bf215546Sopenharmony_ci goto out; 953bf215546Sopenharmony_ci } 954bf215546Sopenharmony_ci } 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) { 957bf215546Sopenharmony_ci i = ureg->nr_immediates++; 958bf215546Sopenharmony_ci ureg->immediate[i].type = type; 959bf215546Sopenharmony_ci if (match_or_expand_immediate(v, 960bf215546Sopenharmony_ci type, 961bf215546Sopenharmony_ci nr, 962bf215546Sopenharmony_ci ureg->immediate[i].value.u, 963bf215546Sopenharmony_ci &ureg->immediate[i].nr, 964bf215546Sopenharmony_ci &swizzle)) { 965bf215546Sopenharmony_ci goto out; 966bf215546Sopenharmony_ci } 967bf215546Sopenharmony_ci } 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_ci set_bad(ureg); 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ciout: 972bf215546Sopenharmony_ci /* Make sure that all referenced elements are from this immediate. 973bf215546Sopenharmony_ci * Has the effect of making size-one immediates into scalars. 974bf215546Sopenharmony_ci */ 975bf215546Sopenharmony_ci if (type == TGSI_IMM_FLOAT64 || 976bf215546Sopenharmony_ci type == TGSI_IMM_UINT64 || 977bf215546Sopenharmony_ci type == TGSI_IMM_INT64) { 978bf215546Sopenharmony_ci for (j = nr; j < 4; j+=2) { 979bf215546Sopenharmony_ci swizzle |= (swizzle & 0xf) << (j * 2); 980bf215546Sopenharmony_ci } 981bf215546Sopenharmony_ci } else { 982bf215546Sopenharmony_ci for (j = nr; j < 4; j++) { 983bf215546Sopenharmony_ci swizzle |= (swizzle & 0x3) << (j * 2); 984bf215546Sopenharmony_ci } 985bf215546Sopenharmony_ci } 986bf215546Sopenharmony_ci return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i), 987bf215546Sopenharmony_ci (swizzle >> 0) & 0x3, 988bf215546Sopenharmony_ci (swizzle >> 2) & 0x3, 989bf215546Sopenharmony_ci (swizzle >> 4) & 0x3, 990bf215546Sopenharmony_ci (swizzle >> 6) & 0x3); 991bf215546Sopenharmony_ci} 992bf215546Sopenharmony_ci 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_cistruct ureg_src 995bf215546Sopenharmony_ciureg_DECL_immediate( struct ureg_program *ureg, 996bf215546Sopenharmony_ci const float *v, 997bf215546Sopenharmony_ci unsigned nr ) 998bf215546Sopenharmony_ci{ 999bf215546Sopenharmony_ci union { 1000bf215546Sopenharmony_ci float f[4]; 1001bf215546Sopenharmony_ci unsigned u[4]; 1002bf215546Sopenharmony_ci } fu; 1003bf215546Sopenharmony_ci unsigned int i; 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci for (i = 0; i < nr; i++) { 1006bf215546Sopenharmony_ci fu.f[i] = v[i]; 1007bf215546Sopenharmony_ci } 1008bf215546Sopenharmony_ci 1009bf215546Sopenharmony_ci return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32); 1010bf215546Sopenharmony_ci} 1011bf215546Sopenharmony_ci 1012bf215546Sopenharmony_cistruct ureg_src 1013bf215546Sopenharmony_ciureg_DECL_immediate_f64( struct ureg_program *ureg, 1014bf215546Sopenharmony_ci const double *v, 1015bf215546Sopenharmony_ci unsigned nr ) 1016bf215546Sopenharmony_ci{ 1017bf215546Sopenharmony_ci union { 1018bf215546Sopenharmony_ci unsigned u[4]; 1019bf215546Sopenharmony_ci double d[2]; 1020bf215546Sopenharmony_ci } fu; 1021bf215546Sopenharmony_ci unsigned int i; 1022bf215546Sopenharmony_ci 1023bf215546Sopenharmony_ci assert((nr / 2) < 3); 1024bf215546Sopenharmony_ci for (i = 0; i < nr / 2; i++) { 1025bf215546Sopenharmony_ci fu.d[i] = v[i]; 1026bf215546Sopenharmony_ci } 1027bf215546Sopenharmony_ci 1028bf215546Sopenharmony_ci return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT64); 1029bf215546Sopenharmony_ci} 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_cistruct ureg_src 1032bf215546Sopenharmony_ciureg_DECL_immediate_uint( struct ureg_program *ureg, 1033bf215546Sopenharmony_ci const unsigned *v, 1034bf215546Sopenharmony_ci unsigned nr ) 1035bf215546Sopenharmony_ci{ 1036bf215546Sopenharmony_ci return decl_immediate(ureg, v, nr, TGSI_IMM_UINT32); 1037bf215546Sopenharmony_ci} 1038bf215546Sopenharmony_ci 1039bf215546Sopenharmony_ci 1040bf215546Sopenharmony_cistruct ureg_src 1041bf215546Sopenharmony_ciureg_DECL_immediate_block_uint( struct ureg_program *ureg, 1042bf215546Sopenharmony_ci const unsigned *v, 1043bf215546Sopenharmony_ci unsigned nr ) 1044bf215546Sopenharmony_ci{ 1045bf215546Sopenharmony_ci uint index; 1046bf215546Sopenharmony_ci uint i; 1047bf215546Sopenharmony_ci 1048bf215546Sopenharmony_ci if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) { 1049bf215546Sopenharmony_ci set_bad(ureg); 1050bf215546Sopenharmony_ci return ureg_src_register(TGSI_FILE_IMMEDIATE, 0); 1051bf215546Sopenharmony_ci } 1052bf215546Sopenharmony_ci 1053bf215546Sopenharmony_ci index = ureg->nr_immediates; 1054bf215546Sopenharmony_ci ureg->nr_immediates += (nr + 3) / 4; 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci for (i = index; i < ureg->nr_immediates; i++) { 1057bf215546Sopenharmony_ci ureg->immediate[i].type = TGSI_IMM_UINT32; 1058bf215546Sopenharmony_ci ureg->immediate[i].nr = nr > 4 ? 4 : nr; 1059bf215546Sopenharmony_ci memcpy(ureg->immediate[i].value.u, 1060bf215546Sopenharmony_ci &v[(i - index) * 4], 1061bf215546Sopenharmony_ci ureg->immediate[i].nr * sizeof(uint)); 1062bf215546Sopenharmony_ci nr -= 4; 1063bf215546Sopenharmony_ci } 1064bf215546Sopenharmony_ci 1065bf215546Sopenharmony_ci return ureg_src_register(TGSI_FILE_IMMEDIATE, index); 1066bf215546Sopenharmony_ci} 1067bf215546Sopenharmony_ci 1068bf215546Sopenharmony_ci 1069bf215546Sopenharmony_cistruct ureg_src 1070bf215546Sopenharmony_ciureg_DECL_immediate_int( struct ureg_program *ureg, 1071bf215546Sopenharmony_ci const int *v, 1072bf215546Sopenharmony_ci unsigned nr ) 1073bf215546Sopenharmony_ci{ 1074bf215546Sopenharmony_ci return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32); 1075bf215546Sopenharmony_ci} 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_cistruct ureg_src 1078bf215546Sopenharmony_ciureg_DECL_immediate_uint64( struct ureg_program *ureg, 1079bf215546Sopenharmony_ci const uint64_t *v, 1080bf215546Sopenharmony_ci unsigned nr ) 1081bf215546Sopenharmony_ci{ 1082bf215546Sopenharmony_ci union { 1083bf215546Sopenharmony_ci unsigned u[4]; 1084bf215546Sopenharmony_ci uint64_t u64[2]; 1085bf215546Sopenharmony_ci } fu; 1086bf215546Sopenharmony_ci unsigned int i; 1087bf215546Sopenharmony_ci 1088bf215546Sopenharmony_ci assert((nr / 2) < 3); 1089bf215546Sopenharmony_ci for (i = 0; i < nr / 2; i++) { 1090bf215546Sopenharmony_ci fu.u64[i] = v[i]; 1091bf215546Sopenharmony_ci } 1092bf215546Sopenharmony_ci 1093bf215546Sopenharmony_ci return decl_immediate(ureg, fu.u, nr, TGSI_IMM_UINT64); 1094bf215546Sopenharmony_ci} 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_cistruct ureg_src 1097bf215546Sopenharmony_ciureg_DECL_immediate_int64( struct ureg_program *ureg, 1098bf215546Sopenharmony_ci const int64_t *v, 1099bf215546Sopenharmony_ci unsigned nr ) 1100bf215546Sopenharmony_ci{ 1101bf215546Sopenharmony_ci union { 1102bf215546Sopenharmony_ci unsigned u[4]; 1103bf215546Sopenharmony_ci int64_t i64[2]; 1104bf215546Sopenharmony_ci } fu; 1105bf215546Sopenharmony_ci unsigned int i; 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_ci assert((nr / 2) < 3); 1108bf215546Sopenharmony_ci for (i = 0; i < nr / 2; i++) { 1109bf215546Sopenharmony_ci fu.i64[i] = v[i]; 1110bf215546Sopenharmony_ci } 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_ci return decl_immediate(ureg, fu.u, nr, TGSI_IMM_INT64); 1113bf215546Sopenharmony_ci} 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_civoid 1116bf215546Sopenharmony_ciureg_emit_src( struct ureg_program *ureg, 1117bf215546Sopenharmony_ci struct ureg_src src ) 1118bf215546Sopenharmony_ci{ 1119bf215546Sopenharmony_ci unsigned size = 1 + (src.Indirect ? 1 : 0) + 1120bf215546Sopenharmony_ci (src.Dimension ? (src.DimIndirect ? 2 : 1) : 0); 1121bf215546Sopenharmony_ci 1122bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size ); 1123bf215546Sopenharmony_ci unsigned n = 0; 1124bf215546Sopenharmony_ci 1125bf215546Sopenharmony_ci assert(src.File != TGSI_FILE_NULL); 1126bf215546Sopenharmony_ci assert(src.File < TGSI_FILE_COUNT); 1127bf215546Sopenharmony_ci 1128bf215546Sopenharmony_ci out[n].value = 0; 1129bf215546Sopenharmony_ci out[n].src.File = src.File; 1130bf215546Sopenharmony_ci out[n].src.SwizzleX = src.SwizzleX; 1131bf215546Sopenharmony_ci out[n].src.SwizzleY = src.SwizzleY; 1132bf215546Sopenharmony_ci out[n].src.SwizzleZ = src.SwizzleZ; 1133bf215546Sopenharmony_ci out[n].src.SwizzleW = src.SwizzleW; 1134bf215546Sopenharmony_ci out[n].src.Index = src.Index; 1135bf215546Sopenharmony_ci out[n].src.Negate = src.Negate; 1136bf215546Sopenharmony_ci out[0].src.Absolute = src.Absolute; 1137bf215546Sopenharmony_ci n++; 1138bf215546Sopenharmony_ci 1139bf215546Sopenharmony_ci if (src.Indirect) { 1140bf215546Sopenharmony_ci out[0].src.Indirect = 1; 1141bf215546Sopenharmony_ci out[n].value = 0; 1142bf215546Sopenharmony_ci out[n].ind.File = src.IndirectFile; 1143bf215546Sopenharmony_ci out[n].ind.Swizzle = src.IndirectSwizzle; 1144bf215546Sopenharmony_ci out[n].ind.Index = src.IndirectIndex; 1145bf215546Sopenharmony_ci if (!ureg->supports_any_inout_decl_range && 1146bf215546Sopenharmony_ci (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT)) 1147bf215546Sopenharmony_ci out[n].ind.ArrayID = 0; 1148bf215546Sopenharmony_ci else 1149bf215546Sopenharmony_ci out[n].ind.ArrayID = src.ArrayID; 1150bf215546Sopenharmony_ci n++; 1151bf215546Sopenharmony_ci } 1152bf215546Sopenharmony_ci 1153bf215546Sopenharmony_ci if (src.Dimension) { 1154bf215546Sopenharmony_ci out[0].src.Dimension = 1; 1155bf215546Sopenharmony_ci out[n].dim.Dimension = 0; 1156bf215546Sopenharmony_ci out[n].dim.Padding = 0; 1157bf215546Sopenharmony_ci if (src.DimIndirect) { 1158bf215546Sopenharmony_ci out[n].dim.Indirect = 1; 1159bf215546Sopenharmony_ci out[n].dim.Index = src.DimensionIndex; 1160bf215546Sopenharmony_ci n++; 1161bf215546Sopenharmony_ci out[n].value = 0; 1162bf215546Sopenharmony_ci out[n].ind.File = src.DimIndFile; 1163bf215546Sopenharmony_ci out[n].ind.Swizzle = src.DimIndSwizzle; 1164bf215546Sopenharmony_ci out[n].ind.Index = src.DimIndIndex; 1165bf215546Sopenharmony_ci if (!ureg->supports_any_inout_decl_range && 1166bf215546Sopenharmony_ci (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT)) 1167bf215546Sopenharmony_ci out[n].ind.ArrayID = 0; 1168bf215546Sopenharmony_ci else 1169bf215546Sopenharmony_ci out[n].ind.ArrayID = src.ArrayID; 1170bf215546Sopenharmony_ci } else { 1171bf215546Sopenharmony_ci out[n].dim.Indirect = 0; 1172bf215546Sopenharmony_ci out[n].dim.Index = src.DimensionIndex; 1173bf215546Sopenharmony_ci } 1174bf215546Sopenharmony_ci n++; 1175bf215546Sopenharmony_ci } 1176bf215546Sopenharmony_ci 1177bf215546Sopenharmony_ci assert(n == size); 1178bf215546Sopenharmony_ci} 1179bf215546Sopenharmony_ci 1180bf215546Sopenharmony_ci 1181bf215546Sopenharmony_civoid 1182bf215546Sopenharmony_ciureg_emit_dst( struct ureg_program *ureg, 1183bf215546Sopenharmony_ci struct ureg_dst dst ) 1184bf215546Sopenharmony_ci{ 1185bf215546Sopenharmony_ci unsigned size = 1 + (dst.Indirect ? 1 : 0) + 1186bf215546Sopenharmony_ci (dst.Dimension ? (dst.DimIndirect ? 2 : 1) : 0); 1187bf215546Sopenharmony_ci 1188bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size ); 1189bf215546Sopenharmony_ci unsigned n = 0; 1190bf215546Sopenharmony_ci 1191bf215546Sopenharmony_ci assert(dst.File != TGSI_FILE_NULL); 1192bf215546Sopenharmony_ci assert(dst.File != TGSI_FILE_SAMPLER); 1193bf215546Sopenharmony_ci assert(dst.File != TGSI_FILE_SAMPLER_VIEW); 1194bf215546Sopenharmony_ci assert(dst.File != TGSI_FILE_IMMEDIATE); 1195bf215546Sopenharmony_ci assert(dst.File < TGSI_FILE_COUNT); 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_ci out[n].value = 0; 1198bf215546Sopenharmony_ci out[n].dst.File = dst.File; 1199bf215546Sopenharmony_ci out[n].dst.WriteMask = dst.WriteMask; 1200bf215546Sopenharmony_ci out[n].dst.Indirect = dst.Indirect; 1201bf215546Sopenharmony_ci out[n].dst.Index = dst.Index; 1202bf215546Sopenharmony_ci n++; 1203bf215546Sopenharmony_ci 1204bf215546Sopenharmony_ci if (dst.Indirect) { 1205bf215546Sopenharmony_ci out[n].value = 0; 1206bf215546Sopenharmony_ci out[n].ind.File = dst.IndirectFile; 1207bf215546Sopenharmony_ci out[n].ind.Swizzle = dst.IndirectSwizzle; 1208bf215546Sopenharmony_ci out[n].ind.Index = dst.IndirectIndex; 1209bf215546Sopenharmony_ci if (!ureg->supports_any_inout_decl_range && 1210bf215546Sopenharmony_ci (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT)) 1211bf215546Sopenharmony_ci out[n].ind.ArrayID = 0; 1212bf215546Sopenharmony_ci else 1213bf215546Sopenharmony_ci out[n].ind.ArrayID = dst.ArrayID; 1214bf215546Sopenharmony_ci n++; 1215bf215546Sopenharmony_ci } 1216bf215546Sopenharmony_ci 1217bf215546Sopenharmony_ci if (dst.Dimension) { 1218bf215546Sopenharmony_ci out[0].dst.Dimension = 1; 1219bf215546Sopenharmony_ci out[n].dim.Dimension = 0; 1220bf215546Sopenharmony_ci out[n].dim.Padding = 0; 1221bf215546Sopenharmony_ci if (dst.DimIndirect) { 1222bf215546Sopenharmony_ci out[n].dim.Indirect = 1; 1223bf215546Sopenharmony_ci out[n].dim.Index = dst.DimensionIndex; 1224bf215546Sopenharmony_ci n++; 1225bf215546Sopenharmony_ci out[n].value = 0; 1226bf215546Sopenharmony_ci out[n].ind.File = dst.DimIndFile; 1227bf215546Sopenharmony_ci out[n].ind.Swizzle = dst.DimIndSwizzle; 1228bf215546Sopenharmony_ci out[n].ind.Index = dst.DimIndIndex; 1229bf215546Sopenharmony_ci if (!ureg->supports_any_inout_decl_range && 1230bf215546Sopenharmony_ci (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT)) 1231bf215546Sopenharmony_ci out[n].ind.ArrayID = 0; 1232bf215546Sopenharmony_ci else 1233bf215546Sopenharmony_ci out[n].ind.ArrayID = dst.ArrayID; 1234bf215546Sopenharmony_ci } else { 1235bf215546Sopenharmony_ci out[n].dim.Indirect = 0; 1236bf215546Sopenharmony_ci out[n].dim.Index = dst.DimensionIndex; 1237bf215546Sopenharmony_ci } 1238bf215546Sopenharmony_ci n++; 1239bf215546Sopenharmony_ci } 1240bf215546Sopenharmony_ci 1241bf215546Sopenharmony_ci assert(n == size); 1242bf215546Sopenharmony_ci} 1243bf215546Sopenharmony_ci 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_cistatic void validate( enum tgsi_opcode opcode, 1246bf215546Sopenharmony_ci unsigned nr_dst, 1247bf215546Sopenharmony_ci unsigned nr_src ) 1248bf215546Sopenharmony_ci{ 1249bf215546Sopenharmony_ci#ifndef NDEBUG 1250bf215546Sopenharmony_ci const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode ); 1251bf215546Sopenharmony_ci assert(info); 1252bf215546Sopenharmony_ci if (info) { 1253bf215546Sopenharmony_ci assert(nr_dst == info->num_dst); 1254bf215546Sopenharmony_ci assert(nr_src == info->num_src); 1255bf215546Sopenharmony_ci } 1256bf215546Sopenharmony_ci#endif 1257bf215546Sopenharmony_ci} 1258bf215546Sopenharmony_ci 1259bf215546Sopenharmony_cistruct ureg_emit_insn_result 1260bf215546Sopenharmony_ciureg_emit_insn(struct ureg_program *ureg, 1261bf215546Sopenharmony_ci enum tgsi_opcode opcode, 1262bf215546Sopenharmony_ci boolean saturate, 1263bf215546Sopenharmony_ci unsigned precise, 1264bf215546Sopenharmony_ci unsigned num_dst, 1265bf215546Sopenharmony_ci unsigned num_src) 1266bf215546Sopenharmony_ci{ 1267bf215546Sopenharmony_ci union tgsi_any_token *out; 1268bf215546Sopenharmony_ci uint count = 1; 1269bf215546Sopenharmony_ci struct ureg_emit_insn_result result; 1270bf215546Sopenharmony_ci 1271bf215546Sopenharmony_ci validate( opcode, num_dst, num_src ); 1272bf215546Sopenharmony_ci 1273bf215546Sopenharmony_ci out = get_tokens( ureg, DOMAIN_INSN, count ); 1274bf215546Sopenharmony_ci out[0].insn = tgsi_default_instruction(); 1275bf215546Sopenharmony_ci out[0].insn.Opcode = opcode; 1276bf215546Sopenharmony_ci out[0].insn.Saturate = saturate; 1277bf215546Sopenharmony_ci out[0].insn.Precise = precise || ureg->precise; 1278bf215546Sopenharmony_ci out[0].insn.NumDstRegs = num_dst; 1279bf215546Sopenharmony_ci out[0].insn.NumSrcRegs = num_src; 1280bf215546Sopenharmony_ci 1281bf215546Sopenharmony_ci result.insn_token = ureg->domain[DOMAIN_INSN].count - count; 1282bf215546Sopenharmony_ci result.extended_token = result.insn_token; 1283bf215546Sopenharmony_ci 1284bf215546Sopenharmony_ci ureg->nr_instructions++; 1285bf215546Sopenharmony_ci 1286bf215546Sopenharmony_ci return result; 1287bf215546Sopenharmony_ci} 1288bf215546Sopenharmony_ci 1289bf215546Sopenharmony_ci 1290bf215546Sopenharmony_ci/** 1291bf215546Sopenharmony_ci * Emit a label token. 1292bf215546Sopenharmony_ci * \param label_token returns a token number indicating where the label 1293bf215546Sopenharmony_ci * needs to be patched later. Later, this value should be passed to the 1294bf215546Sopenharmony_ci * ureg_fixup_label() function. 1295bf215546Sopenharmony_ci */ 1296bf215546Sopenharmony_civoid 1297bf215546Sopenharmony_ciureg_emit_label(struct ureg_program *ureg, 1298bf215546Sopenharmony_ci unsigned extended_token, 1299bf215546Sopenharmony_ci unsigned *label_token ) 1300bf215546Sopenharmony_ci{ 1301bf215546Sopenharmony_ci union tgsi_any_token *out, *insn; 1302bf215546Sopenharmony_ci 1303bf215546Sopenharmony_ci if (!label_token) 1304bf215546Sopenharmony_ci return; 1305bf215546Sopenharmony_ci 1306bf215546Sopenharmony_ci out = get_tokens( ureg, DOMAIN_INSN, 1 ); 1307bf215546Sopenharmony_ci out[0].value = 0; 1308bf215546Sopenharmony_ci 1309bf215546Sopenharmony_ci insn = retrieve_token( ureg, DOMAIN_INSN, extended_token ); 1310bf215546Sopenharmony_ci insn->insn.Label = 1; 1311bf215546Sopenharmony_ci 1312bf215546Sopenharmony_ci *label_token = ureg->domain[DOMAIN_INSN].count - 1; 1313bf215546Sopenharmony_ci} 1314bf215546Sopenharmony_ci 1315bf215546Sopenharmony_ci/* Will return a number which can be used in a label to point to the 1316bf215546Sopenharmony_ci * next instruction to be emitted. 1317bf215546Sopenharmony_ci */ 1318bf215546Sopenharmony_ciunsigned 1319bf215546Sopenharmony_ciureg_get_instruction_number( struct ureg_program *ureg ) 1320bf215546Sopenharmony_ci{ 1321bf215546Sopenharmony_ci return ureg->nr_instructions; 1322bf215546Sopenharmony_ci} 1323bf215546Sopenharmony_ci 1324bf215546Sopenharmony_ci/* Patch a given label (expressed as a token number) to point to a 1325bf215546Sopenharmony_ci * given instruction (expressed as an instruction number). 1326bf215546Sopenharmony_ci */ 1327bf215546Sopenharmony_civoid 1328bf215546Sopenharmony_ciureg_fixup_label(struct ureg_program *ureg, 1329bf215546Sopenharmony_ci unsigned label_token, 1330bf215546Sopenharmony_ci unsigned instruction_number ) 1331bf215546Sopenharmony_ci{ 1332bf215546Sopenharmony_ci union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token ); 1333bf215546Sopenharmony_ci 1334bf215546Sopenharmony_ci out->insn_label.Label = instruction_number; 1335bf215546Sopenharmony_ci} 1336bf215546Sopenharmony_ci 1337bf215546Sopenharmony_ci 1338bf215546Sopenharmony_civoid 1339bf215546Sopenharmony_ciureg_emit_texture(struct ureg_program *ureg, 1340bf215546Sopenharmony_ci unsigned extended_token, 1341bf215546Sopenharmony_ci enum tgsi_texture_type target, 1342bf215546Sopenharmony_ci enum tgsi_return_type return_type, unsigned num_offsets) 1343bf215546Sopenharmony_ci{ 1344bf215546Sopenharmony_ci union tgsi_any_token *out, *insn; 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_ci out = get_tokens( ureg, DOMAIN_INSN, 1 ); 1347bf215546Sopenharmony_ci insn = retrieve_token( ureg, DOMAIN_INSN, extended_token ); 1348bf215546Sopenharmony_ci 1349bf215546Sopenharmony_ci insn->insn.Texture = 1; 1350bf215546Sopenharmony_ci 1351bf215546Sopenharmony_ci out[0].value = 0; 1352bf215546Sopenharmony_ci out[0].insn_texture.Texture = target; 1353bf215546Sopenharmony_ci out[0].insn_texture.NumOffsets = num_offsets; 1354bf215546Sopenharmony_ci out[0].insn_texture.ReturnType = return_type; 1355bf215546Sopenharmony_ci} 1356bf215546Sopenharmony_ci 1357bf215546Sopenharmony_civoid 1358bf215546Sopenharmony_ciureg_emit_texture_offset(struct ureg_program *ureg, 1359bf215546Sopenharmony_ci const struct tgsi_texture_offset *offset) 1360bf215546Sopenharmony_ci{ 1361bf215546Sopenharmony_ci union tgsi_any_token *out; 1362bf215546Sopenharmony_ci 1363bf215546Sopenharmony_ci out = get_tokens( ureg, DOMAIN_INSN, 1); 1364bf215546Sopenharmony_ci 1365bf215546Sopenharmony_ci out[0].value = 0; 1366bf215546Sopenharmony_ci out[0].insn_texture_offset = *offset; 1367bf215546Sopenharmony_ci} 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_civoid 1370bf215546Sopenharmony_ciureg_emit_memory(struct ureg_program *ureg, 1371bf215546Sopenharmony_ci unsigned extended_token, 1372bf215546Sopenharmony_ci unsigned qualifier, 1373bf215546Sopenharmony_ci enum tgsi_texture_type texture, 1374bf215546Sopenharmony_ci enum pipe_format format) 1375bf215546Sopenharmony_ci{ 1376bf215546Sopenharmony_ci union tgsi_any_token *out, *insn; 1377bf215546Sopenharmony_ci 1378bf215546Sopenharmony_ci out = get_tokens( ureg, DOMAIN_INSN, 1 ); 1379bf215546Sopenharmony_ci insn = retrieve_token( ureg, DOMAIN_INSN, extended_token ); 1380bf215546Sopenharmony_ci 1381bf215546Sopenharmony_ci insn->insn.Memory = 1; 1382bf215546Sopenharmony_ci 1383bf215546Sopenharmony_ci out[0].value = 0; 1384bf215546Sopenharmony_ci out[0].insn_memory.Qualifier = qualifier; 1385bf215546Sopenharmony_ci out[0].insn_memory.Texture = texture; 1386bf215546Sopenharmony_ci out[0].insn_memory.Format = format; 1387bf215546Sopenharmony_ci} 1388bf215546Sopenharmony_ci 1389bf215546Sopenharmony_civoid 1390bf215546Sopenharmony_ciureg_fixup_insn_size(struct ureg_program *ureg, 1391bf215546Sopenharmony_ci unsigned insn ) 1392bf215546Sopenharmony_ci{ 1393bf215546Sopenharmony_ci union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn ); 1394bf215546Sopenharmony_ci 1395bf215546Sopenharmony_ci assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION); 1396bf215546Sopenharmony_ci out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1; 1397bf215546Sopenharmony_ci} 1398bf215546Sopenharmony_ci 1399bf215546Sopenharmony_ci 1400bf215546Sopenharmony_civoid 1401bf215546Sopenharmony_ciureg_insn(struct ureg_program *ureg, 1402bf215546Sopenharmony_ci enum tgsi_opcode opcode, 1403bf215546Sopenharmony_ci const struct ureg_dst *dst, 1404bf215546Sopenharmony_ci unsigned nr_dst, 1405bf215546Sopenharmony_ci const struct ureg_src *src, 1406bf215546Sopenharmony_ci unsigned nr_src, 1407bf215546Sopenharmony_ci unsigned precise ) 1408bf215546Sopenharmony_ci{ 1409bf215546Sopenharmony_ci struct ureg_emit_insn_result insn; 1410bf215546Sopenharmony_ci unsigned i; 1411bf215546Sopenharmony_ci boolean saturate; 1412bf215546Sopenharmony_ci 1413bf215546Sopenharmony_ci if (nr_dst && ureg_dst_is_empty(dst[0])) { 1414bf215546Sopenharmony_ci return; 1415bf215546Sopenharmony_ci } 1416bf215546Sopenharmony_ci 1417bf215546Sopenharmony_ci saturate = nr_dst ? dst[0].Saturate : FALSE; 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_ci insn = ureg_emit_insn(ureg, 1420bf215546Sopenharmony_ci opcode, 1421bf215546Sopenharmony_ci saturate, 1422bf215546Sopenharmony_ci precise, 1423bf215546Sopenharmony_ci nr_dst, 1424bf215546Sopenharmony_ci nr_src); 1425bf215546Sopenharmony_ci 1426bf215546Sopenharmony_ci for (i = 0; i < nr_dst; i++) 1427bf215546Sopenharmony_ci ureg_emit_dst( ureg, dst[i] ); 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci for (i = 0; i < nr_src; i++) 1430bf215546Sopenharmony_ci ureg_emit_src( ureg, src[i] ); 1431bf215546Sopenharmony_ci 1432bf215546Sopenharmony_ci ureg_fixup_insn_size( ureg, insn.insn_token ); 1433bf215546Sopenharmony_ci} 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_civoid 1436bf215546Sopenharmony_ciureg_tex_insn(struct ureg_program *ureg, 1437bf215546Sopenharmony_ci enum tgsi_opcode opcode, 1438bf215546Sopenharmony_ci const struct ureg_dst *dst, 1439bf215546Sopenharmony_ci unsigned nr_dst, 1440bf215546Sopenharmony_ci enum tgsi_texture_type target, 1441bf215546Sopenharmony_ci enum tgsi_return_type return_type, 1442bf215546Sopenharmony_ci const struct tgsi_texture_offset *texoffsets, 1443bf215546Sopenharmony_ci unsigned nr_offset, 1444bf215546Sopenharmony_ci const struct ureg_src *src, 1445bf215546Sopenharmony_ci unsigned nr_src ) 1446bf215546Sopenharmony_ci{ 1447bf215546Sopenharmony_ci struct ureg_emit_insn_result insn; 1448bf215546Sopenharmony_ci unsigned i; 1449bf215546Sopenharmony_ci boolean saturate; 1450bf215546Sopenharmony_ci 1451bf215546Sopenharmony_ci if (nr_dst && ureg_dst_is_empty(dst[0])) { 1452bf215546Sopenharmony_ci return; 1453bf215546Sopenharmony_ci } 1454bf215546Sopenharmony_ci 1455bf215546Sopenharmony_ci saturate = nr_dst ? dst[0].Saturate : FALSE; 1456bf215546Sopenharmony_ci 1457bf215546Sopenharmony_ci insn = ureg_emit_insn(ureg, 1458bf215546Sopenharmony_ci opcode, 1459bf215546Sopenharmony_ci saturate, 1460bf215546Sopenharmony_ci 0, 1461bf215546Sopenharmony_ci nr_dst, 1462bf215546Sopenharmony_ci nr_src); 1463bf215546Sopenharmony_ci 1464bf215546Sopenharmony_ci ureg_emit_texture( ureg, insn.extended_token, target, return_type, 1465bf215546Sopenharmony_ci nr_offset ); 1466bf215546Sopenharmony_ci 1467bf215546Sopenharmony_ci for (i = 0; i < nr_offset; i++) 1468bf215546Sopenharmony_ci ureg_emit_texture_offset( ureg, &texoffsets[i]); 1469bf215546Sopenharmony_ci 1470bf215546Sopenharmony_ci for (i = 0; i < nr_dst; i++) 1471bf215546Sopenharmony_ci ureg_emit_dst( ureg, dst[i] ); 1472bf215546Sopenharmony_ci 1473bf215546Sopenharmony_ci for (i = 0; i < nr_src; i++) 1474bf215546Sopenharmony_ci ureg_emit_src( ureg, src[i] ); 1475bf215546Sopenharmony_ci 1476bf215546Sopenharmony_ci ureg_fixup_insn_size( ureg, insn.insn_token ); 1477bf215546Sopenharmony_ci} 1478bf215546Sopenharmony_ci 1479bf215546Sopenharmony_ci 1480bf215546Sopenharmony_civoid 1481bf215546Sopenharmony_ciureg_memory_insn(struct ureg_program *ureg, 1482bf215546Sopenharmony_ci enum tgsi_opcode opcode, 1483bf215546Sopenharmony_ci const struct ureg_dst *dst, 1484bf215546Sopenharmony_ci unsigned nr_dst, 1485bf215546Sopenharmony_ci const struct ureg_src *src, 1486bf215546Sopenharmony_ci unsigned nr_src, 1487bf215546Sopenharmony_ci unsigned qualifier, 1488bf215546Sopenharmony_ci enum tgsi_texture_type texture, 1489bf215546Sopenharmony_ci enum pipe_format format) 1490bf215546Sopenharmony_ci{ 1491bf215546Sopenharmony_ci struct ureg_emit_insn_result insn; 1492bf215546Sopenharmony_ci unsigned i; 1493bf215546Sopenharmony_ci 1494bf215546Sopenharmony_ci insn = ureg_emit_insn(ureg, 1495bf215546Sopenharmony_ci opcode, 1496bf215546Sopenharmony_ci FALSE, 1497bf215546Sopenharmony_ci 0, 1498bf215546Sopenharmony_ci nr_dst, 1499bf215546Sopenharmony_ci nr_src); 1500bf215546Sopenharmony_ci 1501bf215546Sopenharmony_ci ureg_emit_memory(ureg, insn.extended_token, qualifier, texture, format); 1502bf215546Sopenharmony_ci 1503bf215546Sopenharmony_ci for (i = 0; i < nr_dst; i++) 1504bf215546Sopenharmony_ci ureg_emit_dst(ureg, dst[i]); 1505bf215546Sopenharmony_ci 1506bf215546Sopenharmony_ci for (i = 0; i < nr_src; i++) 1507bf215546Sopenharmony_ci ureg_emit_src(ureg, src[i]); 1508bf215546Sopenharmony_ci 1509bf215546Sopenharmony_ci ureg_fixup_insn_size(ureg, insn.insn_token); 1510bf215546Sopenharmony_ci} 1511bf215546Sopenharmony_ci 1512bf215546Sopenharmony_ci 1513bf215546Sopenharmony_cistatic void 1514bf215546Sopenharmony_ciemit_decl_semantic(struct ureg_program *ureg, 1515bf215546Sopenharmony_ci unsigned file, 1516bf215546Sopenharmony_ci unsigned first, 1517bf215546Sopenharmony_ci unsigned last, 1518bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 1519bf215546Sopenharmony_ci unsigned semantic_index, 1520bf215546Sopenharmony_ci unsigned streams, 1521bf215546Sopenharmony_ci unsigned usage_mask, 1522bf215546Sopenharmony_ci unsigned array_id, 1523bf215546Sopenharmony_ci boolean invariant) 1524bf215546Sopenharmony_ci{ 1525bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3); 1526bf215546Sopenharmony_ci 1527bf215546Sopenharmony_ci out[0].value = 0; 1528bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1529bf215546Sopenharmony_ci out[0].decl.NrTokens = 3; 1530bf215546Sopenharmony_ci out[0].decl.File = file; 1531bf215546Sopenharmony_ci out[0].decl.UsageMask = usage_mask; 1532bf215546Sopenharmony_ci out[0].decl.Semantic = 1; 1533bf215546Sopenharmony_ci out[0].decl.Array = array_id != 0; 1534bf215546Sopenharmony_ci out[0].decl.Invariant = invariant; 1535bf215546Sopenharmony_ci 1536bf215546Sopenharmony_ci out[1].value = 0; 1537bf215546Sopenharmony_ci out[1].decl_range.First = first; 1538bf215546Sopenharmony_ci out[1].decl_range.Last = last; 1539bf215546Sopenharmony_ci 1540bf215546Sopenharmony_ci out[2].value = 0; 1541bf215546Sopenharmony_ci out[2].decl_semantic.Name = semantic_name; 1542bf215546Sopenharmony_ci out[2].decl_semantic.Index = semantic_index; 1543bf215546Sopenharmony_ci out[2].decl_semantic.StreamX = streams & 3; 1544bf215546Sopenharmony_ci out[2].decl_semantic.StreamY = (streams >> 2) & 3; 1545bf215546Sopenharmony_ci out[2].decl_semantic.StreamZ = (streams >> 4) & 3; 1546bf215546Sopenharmony_ci out[2].decl_semantic.StreamW = (streams >> 6) & 3; 1547bf215546Sopenharmony_ci 1548bf215546Sopenharmony_ci if (array_id) { 1549bf215546Sopenharmony_ci out[3].value = 0; 1550bf215546Sopenharmony_ci out[3].array.ArrayID = array_id; 1551bf215546Sopenharmony_ci } 1552bf215546Sopenharmony_ci} 1553bf215546Sopenharmony_ci 1554bf215546Sopenharmony_cistatic void 1555bf215546Sopenharmony_ciemit_decl_atomic_2d(struct ureg_program *ureg, 1556bf215546Sopenharmony_ci unsigned first, 1557bf215546Sopenharmony_ci unsigned last, 1558bf215546Sopenharmony_ci unsigned index2D, 1559bf215546Sopenharmony_ci unsigned array_id) 1560bf215546Sopenharmony_ci{ 1561bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3); 1562bf215546Sopenharmony_ci 1563bf215546Sopenharmony_ci out[0].value = 0; 1564bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1565bf215546Sopenharmony_ci out[0].decl.NrTokens = 3; 1566bf215546Sopenharmony_ci out[0].decl.File = TGSI_FILE_HW_ATOMIC; 1567bf215546Sopenharmony_ci out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1568bf215546Sopenharmony_ci out[0].decl.Dimension = 1; 1569bf215546Sopenharmony_ci out[0].decl.Array = array_id != 0; 1570bf215546Sopenharmony_ci 1571bf215546Sopenharmony_ci out[1].value = 0; 1572bf215546Sopenharmony_ci out[1].decl_range.First = first; 1573bf215546Sopenharmony_ci out[1].decl_range.Last = last; 1574bf215546Sopenharmony_ci 1575bf215546Sopenharmony_ci out[2].value = 0; 1576bf215546Sopenharmony_ci out[2].decl_dim.Index2D = index2D; 1577bf215546Sopenharmony_ci 1578bf215546Sopenharmony_ci if (array_id) { 1579bf215546Sopenharmony_ci out[3].value = 0; 1580bf215546Sopenharmony_ci out[3].array.ArrayID = array_id; 1581bf215546Sopenharmony_ci } 1582bf215546Sopenharmony_ci} 1583bf215546Sopenharmony_ci 1584bf215546Sopenharmony_cistatic void 1585bf215546Sopenharmony_ciemit_decl_fs(struct ureg_program *ureg, 1586bf215546Sopenharmony_ci unsigned file, 1587bf215546Sopenharmony_ci unsigned first, 1588bf215546Sopenharmony_ci unsigned last, 1589bf215546Sopenharmony_ci enum tgsi_semantic semantic_name, 1590bf215546Sopenharmony_ci unsigned semantic_index, 1591bf215546Sopenharmony_ci enum tgsi_interpolate_mode interpolate, 1592bf215546Sopenharmony_ci enum tgsi_interpolate_loc interpolate_location, 1593bf215546Sopenharmony_ci unsigned array_id, 1594bf215546Sopenharmony_ci unsigned usage_mask) 1595bf215546Sopenharmony_ci{ 1596bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 1597bf215546Sopenharmony_ci array_id ? 5 : 4); 1598bf215546Sopenharmony_ci 1599bf215546Sopenharmony_ci out[0].value = 0; 1600bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1601bf215546Sopenharmony_ci out[0].decl.NrTokens = 4; 1602bf215546Sopenharmony_ci out[0].decl.File = file; 1603bf215546Sopenharmony_ci out[0].decl.UsageMask = usage_mask; 1604bf215546Sopenharmony_ci out[0].decl.Interpolate = 1; 1605bf215546Sopenharmony_ci out[0].decl.Semantic = 1; 1606bf215546Sopenharmony_ci out[0].decl.Array = array_id != 0; 1607bf215546Sopenharmony_ci 1608bf215546Sopenharmony_ci out[1].value = 0; 1609bf215546Sopenharmony_ci out[1].decl_range.First = first; 1610bf215546Sopenharmony_ci out[1].decl_range.Last = last; 1611bf215546Sopenharmony_ci 1612bf215546Sopenharmony_ci out[2].value = 0; 1613bf215546Sopenharmony_ci out[2].decl_interp.Interpolate = interpolate; 1614bf215546Sopenharmony_ci out[2].decl_interp.Location = interpolate_location; 1615bf215546Sopenharmony_ci 1616bf215546Sopenharmony_ci out[3].value = 0; 1617bf215546Sopenharmony_ci out[3].decl_semantic.Name = semantic_name; 1618bf215546Sopenharmony_ci out[3].decl_semantic.Index = semantic_index; 1619bf215546Sopenharmony_ci 1620bf215546Sopenharmony_ci if (array_id) { 1621bf215546Sopenharmony_ci out[4].value = 0; 1622bf215546Sopenharmony_ci out[4].array.ArrayID = array_id; 1623bf215546Sopenharmony_ci } 1624bf215546Sopenharmony_ci} 1625bf215546Sopenharmony_ci 1626bf215546Sopenharmony_cistatic void 1627bf215546Sopenharmony_ciemit_decl_temps( struct ureg_program *ureg, 1628bf215546Sopenharmony_ci unsigned first, unsigned last, 1629bf215546Sopenharmony_ci boolean local, 1630bf215546Sopenharmony_ci unsigned arrayid ) 1631bf215546Sopenharmony_ci{ 1632bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 1633bf215546Sopenharmony_ci arrayid ? 3 : 2 ); 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ci out[0].value = 0; 1636bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1637bf215546Sopenharmony_ci out[0].decl.NrTokens = 2; 1638bf215546Sopenharmony_ci out[0].decl.File = TGSI_FILE_TEMPORARY; 1639bf215546Sopenharmony_ci out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1640bf215546Sopenharmony_ci out[0].decl.Local = local; 1641bf215546Sopenharmony_ci 1642bf215546Sopenharmony_ci out[1].value = 0; 1643bf215546Sopenharmony_ci out[1].decl_range.First = first; 1644bf215546Sopenharmony_ci out[1].decl_range.Last = last; 1645bf215546Sopenharmony_ci 1646bf215546Sopenharmony_ci if (arrayid) { 1647bf215546Sopenharmony_ci out[0].decl.Array = 1; 1648bf215546Sopenharmony_ci out[2].value = 0; 1649bf215546Sopenharmony_ci out[2].array.ArrayID = arrayid; 1650bf215546Sopenharmony_ci } 1651bf215546Sopenharmony_ci} 1652bf215546Sopenharmony_ci 1653bf215546Sopenharmony_cistatic void emit_decl_range( struct ureg_program *ureg, 1654bf215546Sopenharmony_ci unsigned file, 1655bf215546Sopenharmony_ci unsigned first, 1656bf215546Sopenharmony_ci unsigned count ) 1657bf215546Sopenharmony_ci{ 1658bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 ); 1659bf215546Sopenharmony_ci 1660bf215546Sopenharmony_ci out[0].value = 0; 1661bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1662bf215546Sopenharmony_ci out[0].decl.NrTokens = 2; 1663bf215546Sopenharmony_ci out[0].decl.File = file; 1664bf215546Sopenharmony_ci out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1665bf215546Sopenharmony_ci out[0].decl.Semantic = 0; 1666bf215546Sopenharmony_ci 1667bf215546Sopenharmony_ci out[1].value = 0; 1668bf215546Sopenharmony_ci out[1].decl_range.First = first; 1669bf215546Sopenharmony_ci out[1].decl_range.Last = first + count - 1; 1670bf215546Sopenharmony_ci} 1671bf215546Sopenharmony_ci 1672bf215546Sopenharmony_cistatic void 1673bf215546Sopenharmony_ciemit_decl_range2D(struct ureg_program *ureg, 1674bf215546Sopenharmony_ci unsigned file, 1675bf215546Sopenharmony_ci unsigned first, 1676bf215546Sopenharmony_ci unsigned last, 1677bf215546Sopenharmony_ci unsigned index2D) 1678bf215546Sopenharmony_ci{ 1679bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); 1680bf215546Sopenharmony_ci 1681bf215546Sopenharmony_ci out[0].value = 0; 1682bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1683bf215546Sopenharmony_ci out[0].decl.NrTokens = 3; 1684bf215546Sopenharmony_ci out[0].decl.File = file; 1685bf215546Sopenharmony_ci out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1686bf215546Sopenharmony_ci out[0].decl.Dimension = 1; 1687bf215546Sopenharmony_ci 1688bf215546Sopenharmony_ci out[1].value = 0; 1689bf215546Sopenharmony_ci out[1].decl_range.First = first; 1690bf215546Sopenharmony_ci out[1].decl_range.Last = last; 1691bf215546Sopenharmony_ci 1692bf215546Sopenharmony_ci out[2].value = 0; 1693bf215546Sopenharmony_ci out[2].decl_dim.Index2D = index2D; 1694bf215546Sopenharmony_ci} 1695bf215546Sopenharmony_ci 1696bf215546Sopenharmony_cistatic void 1697bf215546Sopenharmony_ciemit_decl_sampler_view(struct ureg_program *ureg, 1698bf215546Sopenharmony_ci unsigned index, 1699bf215546Sopenharmony_ci enum tgsi_texture_type target, 1700bf215546Sopenharmony_ci enum tgsi_return_type return_type_x, 1701bf215546Sopenharmony_ci enum tgsi_return_type return_type_y, 1702bf215546Sopenharmony_ci enum tgsi_return_type return_type_z, 1703bf215546Sopenharmony_ci enum tgsi_return_type return_type_w ) 1704bf215546Sopenharmony_ci{ 1705bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); 1706bf215546Sopenharmony_ci 1707bf215546Sopenharmony_ci out[0].value = 0; 1708bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1709bf215546Sopenharmony_ci out[0].decl.NrTokens = 3; 1710bf215546Sopenharmony_ci out[0].decl.File = TGSI_FILE_SAMPLER_VIEW; 1711bf215546Sopenharmony_ci out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1712bf215546Sopenharmony_ci 1713bf215546Sopenharmony_ci out[1].value = 0; 1714bf215546Sopenharmony_ci out[1].decl_range.First = index; 1715bf215546Sopenharmony_ci out[1].decl_range.Last = index; 1716bf215546Sopenharmony_ci 1717bf215546Sopenharmony_ci out[2].value = 0; 1718bf215546Sopenharmony_ci out[2].decl_sampler_view.Resource = target; 1719bf215546Sopenharmony_ci out[2].decl_sampler_view.ReturnTypeX = return_type_x; 1720bf215546Sopenharmony_ci out[2].decl_sampler_view.ReturnTypeY = return_type_y; 1721bf215546Sopenharmony_ci out[2].decl_sampler_view.ReturnTypeZ = return_type_z; 1722bf215546Sopenharmony_ci out[2].decl_sampler_view.ReturnTypeW = return_type_w; 1723bf215546Sopenharmony_ci} 1724bf215546Sopenharmony_ci 1725bf215546Sopenharmony_cistatic void 1726bf215546Sopenharmony_ciemit_decl_image(struct ureg_program *ureg, 1727bf215546Sopenharmony_ci unsigned index, 1728bf215546Sopenharmony_ci enum tgsi_texture_type target, 1729bf215546Sopenharmony_ci enum pipe_format format, 1730bf215546Sopenharmony_ci boolean wr, 1731bf215546Sopenharmony_ci boolean raw) 1732bf215546Sopenharmony_ci{ 1733bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); 1734bf215546Sopenharmony_ci 1735bf215546Sopenharmony_ci out[0].value = 0; 1736bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1737bf215546Sopenharmony_ci out[0].decl.NrTokens = 3; 1738bf215546Sopenharmony_ci out[0].decl.File = TGSI_FILE_IMAGE; 1739bf215546Sopenharmony_ci out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1740bf215546Sopenharmony_ci 1741bf215546Sopenharmony_ci out[1].value = 0; 1742bf215546Sopenharmony_ci out[1].decl_range.First = index; 1743bf215546Sopenharmony_ci out[1].decl_range.Last = index; 1744bf215546Sopenharmony_ci 1745bf215546Sopenharmony_ci out[2].value = 0; 1746bf215546Sopenharmony_ci out[2].decl_image.Resource = target; 1747bf215546Sopenharmony_ci out[2].decl_image.Writable = wr; 1748bf215546Sopenharmony_ci out[2].decl_image.Raw = raw; 1749bf215546Sopenharmony_ci out[2].decl_image.Format = format; 1750bf215546Sopenharmony_ci} 1751bf215546Sopenharmony_ci 1752bf215546Sopenharmony_cistatic void 1753bf215546Sopenharmony_ciemit_decl_buffer(struct ureg_program *ureg, 1754bf215546Sopenharmony_ci unsigned index, 1755bf215546Sopenharmony_ci bool atomic) 1756bf215546Sopenharmony_ci{ 1757bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2); 1758bf215546Sopenharmony_ci 1759bf215546Sopenharmony_ci out[0].value = 0; 1760bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1761bf215546Sopenharmony_ci out[0].decl.NrTokens = 2; 1762bf215546Sopenharmony_ci out[0].decl.File = TGSI_FILE_BUFFER; 1763bf215546Sopenharmony_ci out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1764bf215546Sopenharmony_ci out[0].decl.Atomic = atomic; 1765bf215546Sopenharmony_ci 1766bf215546Sopenharmony_ci out[1].value = 0; 1767bf215546Sopenharmony_ci out[1].decl_range.First = index; 1768bf215546Sopenharmony_ci out[1].decl_range.Last = index; 1769bf215546Sopenharmony_ci} 1770bf215546Sopenharmony_ci 1771bf215546Sopenharmony_cistatic void 1772bf215546Sopenharmony_ciemit_decl_memory(struct ureg_program *ureg, unsigned memory_type) 1773bf215546Sopenharmony_ci{ 1774bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2); 1775bf215546Sopenharmony_ci 1776bf215546Sopenharmony_ci out[0].value = 0; 1777bf215546Sopenharmony_ci out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1778bf215546Sopenharmony_ci out[0].decl.NrTokens = 2; 1779bf215546Sopenharmony_ci out[0].decl.File = TGSI_FILE_MEMORY; 1780bf215546Sopenharmony_ci out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1781bf215546Sopenharmony_ci out[0].decl.MemType = memory_type; 1782bf215546Sopenharmony_ci 1783bf215546Sopenharmony_ci out[1].value = 0; 1784bf215546Sopenharmony_ci out[1].decl_range.First = memory_type; 1785bf215546Sopenharmony_ci out[1].decl_range.Last = memory_type; 1786bf215546Sopenharmony_ci} 1787bf215546Sopenharmony_ci 1788bf215546Sopenharmony_cistatic void 1789bf215546Sopenharmony_ciemit_immediate( struct ureg_program *ureg, 1790bf215546Sopenharmony_ci const unsigned *v, 1791bf215546Sopenharmony_ci unsigned type ) 1792bf215546Sopenharmony_ci{ 1793bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 ); 1794bf215546Sopenharmony_ci 1795bf215546Sopenharmony_ci out[0].value = 0; 1796bf215546Sopenharmony_ci out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE; 1797bf215546Sopenharmony_ci out[0].imm.NrTokens = 5; 1798bf215546Sopenharmony_ci out[0].imm.DataType = type; 1799bf215546Sopenharmony_ci out[0].imm.Padding = 0; 1800bf215546Sopenharmony_ci 1801bf215546Sopenharmony_ci out[1].imm_data.Uint = v[0]; 1802bf215546Sopenharmony_ci out[2].imm_data.Uint = v[1]; 1803bf215546Sopenharmony_ci out[3].imm_data.Uint = v[2]; 1804bf215546Sopenharmony_ci out[4].imm_data.Uint = v[3]; 1805bf215546Sopenharmony_ci} 1806bf215546Sopenharmony_ci 1807bf215546Sopenharmony_cistatic void 1808bf215546Sopenharmony_ciemit_property(struct ureg_program *ureg, 1809bf215546Sopenharmony_ci unsigned name, 1810bf215546Sopenharmony_ci unsigned data) 1811bf215546Sopenharmony_ci{ 1812bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2); 1813bf215546Sopenharmony_ci 1814bf215546Sopenharmony_ci out[0].value = 0; 1815bf215546Sopenharmony_ci out[0].prop.Type = TGSI_TOKEN_TYPE_PROPERTY; 1816bf215546Sopenharmony_ci out[0].prop.NrTokens = 2; 1817bf215546Sopenharmony_ci out[0].prop.PropertyName = name; 1818bf215546Sopenharmony_ci 1819bf215546Sopenharmony_ci out[1].prop_data.Data = data; 1820bf215546Sopenharmony_ci} 1821bf215546Sopenharmony_ci 1822bf215546Sopenharmony_cistatic int 1823bf215546Sopenharmony_ciinput_sort(const void *in_a, const void *in_b) 1824bf215546Sopenharmony_ci{ 1825bf215546Sopenharmony_ci const struct ureg_input_decl *a = in_a, *b = in_b; 1826bf215546Sopenharmony_ci 1827bf215546Sopenharmony_ci return a->first - b->first; 1828bf215546Sopenharmony_ci} 1829bf215546Sopenharmony_ci 1830bf215546Sopenharmony_cistatic int 1831bf215546Sopenharmony_cioutput_sort(const void *in_a, const void *in_b) 1832bf215546Sopenharmony_ci{ 1833bf215546Sopenharmony_ci const struct ureg_output_decl *a = in_a, *b = in_b; 1834bf215546Sopenharmony_ci 1835bf215546Sopenharmony_ci return a->first - b->first; 1836bf215546Sopenharmony_ci} 1837bf215546Sopenharmony_ci 1838bf215546Sopenharmony_cistatic int 1839bf215546Sopenharmony_ciatomic_decl_range_sort(const void *in_a, const void *in_b) 1840bf215546Sopenharmony_ci{ 1841bf215546Sopenharmony_ci const struct hw_atomic_decl_range *a = in_a, *b = in_b; 1842bf215546Sopenharmony_ci 1843bf215546Sopenharmony_ci return a->first - b->first; 1844bf215546Sopenharmony_ci} 1845bf215546Sopenharmony_ci 1846bf215546Sopenharmony_cistatic void emit_decls( struct ureg_program *ureg ) 1847bf215546Sopenharmony_ci{ 1848bf215546Sopenharmony_ci unsigned i,j; 1849bf215546Sopenharmony_ci 1850bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ureg->properties); i++) 1851bf215546Sopenharmony_ci if (ureg->properties[i] != ~0u) 1852bf215546Sopenharmony_ci emit_property(ureg, i, ureg->properties[i]); 1853bf215546Sopenharmony_ci 1854bf215546Sopenharmony_ci /* While not required by TGSI spec, virglrenderer has a dependency on the 1855bf215546Sopenharmony_ci * inputs being sorted. 1856bf215546Sopenharmony_ci */ 1857bf215546Sopenharmony_ci qsort(ureg->input, ureg->nr_inputs, sizeof(ureg->input[0]), input_sort); 1858bf215546Sopenharmony_ci 1859bf215546Sopenharmony_ci if (ureg->processor == PIPE_SHADER_VERTEX) { 1860bf215546Sopenharmony_ci for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { 1861bf215546Sopenharmony_ci if (ureg->vs_inputs[i/32] & (1u << (i%32))) { 1862bf215546Sopenharmony_ci emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 ); 1863bf215546Sopenharmony_ci } 1864bf215546Sopenharmony_ci } 1865bf215546Sopenharmony_ci } else if (ureg->processor == PIPE_SHADER_FRAGMENT) { 1866bf215546Sopenharmony_ci if (ureg->supports_any_inout_decl_range) { 1867bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_inputs; i++) { 1868bf215546Sopenharmony_ci emit_decl_fs(ureg, 1869bf215546Sopenharmony_ci TGSI_FILE_INPUT, 1870bf215546Sopenharmony_ci ureg->input[i].first, 1871bf215546Sopenharmony_ci ureg->input[i].last, 1872bf215546Sopenharmony_ci ureg->input[i].semantic_name, 1873bf215546Sopenharmony_ci ureg->input[i].semantic_index, 1874bf215546Sopenharmony_ci ureg->input[i].interp, 1875bf215546Sopenharmony_ci ureg->input[i].interp_location, 1876bf215546Sopenharmony_ci ureg->input[i].array_id, 1877bf215546Sopenharmony_ci ureg->input[i].usage_mask); 1878bf215546Sopenharmony_ci } 1879bf215546Sopenharmony_ci } 1880bf215546Sopenharmony_ci else { 1881bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_inputs; i++) { 1882bf215546Sopenharmony_ci for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) { 1883bf215546Sopenharmony_ci emit_decl_fs(ureg, 1884bf215546Sopenharmony_ci TGSI_FILE_INPUT, 1885bf215546Sopenharmony_ci j, j, 1886bf215546Sopenharmony_ci ureg->input[i].semantic_name, 1887bf215546Sopenharmony_ci ureg->input[i].semantic_index + 1888bf215546Sopenharmony_ci (j - ureg->input[i].first), 1889bf215546Sopenharmony_ci ureg->input[i].interp, 1890bf215546Sopenharmony_ci ureg->input[i].interp_location, 0, 1891bf215546Sopenharmony_ci ureg->input[i].usage_mask); 1892bf215546Sopenharmony_ci } 1893bf215546Sopenharmony_ci } 1894bf215546Sopenharmony_ci } 1895bf215546Sopenharmony_ci } else { 1896bf215546Sopenharmony_ci if (ureg->supports_any_inout_decl_range) { 1897bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_inputs; i++) { 1898bf215546Sopenharmony_ci emit_decl_semantic(ureg, 1899bf215546Sopenharmony_ci TGSI_FILE_INPUT, 1900bf215546Sopenharmony_ci ureg->input[i].first, 1901bf215546Sopenharmony_ci ureg->input[i].last, 1902bf215546Sopenharmony_ci ureg->input[i].semantic_name, 1903bf215546Sopenharmony_ci ureg->input[i].semantic_index, 1904bf215546Sopenharmony_ci 0, 1905bf215546Sopenharmony_ci TGSI_WRITEMASK_XYZW, 1906bf215546Sopenharmony_ci ureg->input[i].array_id, 1907bf215546Sopenharmony_ci FALSE); 1908bf215546Sopenharmony_ci } 1909bf215546Sopenharmony_ci } 1910bf215546Sopenharmony_ci else { 1911bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_inputs; i++) { 1912bf215546Sopenharmony_ci for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) { 1913bf215546Sopenharmony_ci emit_decl_semantic(ureg, 1914bf215546Sopenharmony_ci TGSI_FILE_INPUT, 1915bf215546Sopenharmony_ci j, j, 1916bf215546Sopenharmony_ci ureg->input[i].semantic_name, 1917bf215546Sopenharmony_ci ureg->input[i].semantic_index + 1918bf215546Sopenharmony_ci (j - ureg->input[i].first), 1919bf215546Sopenharmony_ci 0, 1920bf215546Sopenharmony_ci TGSI_WRITEMASK_XYZW, 0, FALSE); 1921bf215546Sopenharmony_ci } 1922bf215546Sopenharmony_ci } 1923bf215546Sopenharmony_ci } 1924bf215546Sopenharmony_ci } 1925bf215546Sopenharmony_ci 1926bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_system_values; i++) { 1927bf215546Sopenharmony_ci emit_decl_semantic(ureg, 1928bf215546Sopenharmony_ci TGSI_FILE_SYSTEM_VALUE, 1929bf215546Sopenharmony_ci i, 1930bf215546Sopenharmony_ci i, 1931bf215546Sopenharmony_ci ureg->system_value[i].semantic_name, 1932bf215546Sopenharmony_ci ureg->system_value[i].semantic_index, 1933bf215546Sopenharmony_ci 0, 1934bf215546Sopenharmony_ci TGSI_WRITEMASK_XYZW, 0, FALSE); 1935bf215546Sopenharmony_ci } 1936bf215546Sopenharmony_ci 1937bf215546Sopenharmony_ci /* While not required by TGSI spec, virglrenderer has a dependency on the 1938bf215546Sopenharmony_ci * outputs being sorted. 1939bf215546Sopenharmony_ci */ 1940bf215546Sopenharmony_ci qsort(ureg->output, ureg->nr_outputs, sizeof(ureg->output[0]), output_sort); 1941bf215546Sopenharmony_ci 1942bf215546Sopenharmony_ci if (ureg->supports_any_inout_decl_range) { 1943bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_outputs; i++) { 1944bf215546Sopenharmony_ci emit_decl_semantic(ureg, 1945bf215546Sopenharmony_ci TGSI_FILE_OUTPUT, 1946bf215546Sopenharmony_ci ureg->output[i].first, 1947bf215546Sopenharmony_ci ureg->output[i].last, 1948bf215546Sopenharmony_ci ureg->output[i].semantic_name, 1949bf215546Sopenharmony_ci ureg->output[i].semantic_index, 1950bf215546Sopenharmony_ci ureg->output[i].streams, 1951bf215546Sopenharmony_ci ureg->output[i].usage_mask, 1952bf215546Sopenharmony_ci ureg->output[i].array_id, 1953bf215546Sopenharmony_ci ureg->output[i].invariant); 1954bf215546Sopenharmony_ci } 1955bf215546Sopenharmony_ci } 1956bf215546Sopenharmony_ci else { 1957bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_outputs; i++) { 1958bf215546Sopenharmony_ci for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) { 1959bf215546Sopenharmony_ci emit_decl_semantic(ureg, 1960bf215546Sopenharmony_ci TGSI_FILE_OUTPUT, 1961bf215546Sopenharmony_ci j, j, 1962bf215546Sopenharmony_ci ureg->output[i].semantic_name, 1963bf215546Sopenharmony_ci ureg->output[i].semantic_index + 1964bf215546Sopenharmony_ci (j - ureg->output[i].first), 1965bf215546Sopenharmony_ci ureg->output[i].streams, 1966bf215546Sopenharmony_ci ureg->output[i].usage_mask, 1967bf215546Sopenharmony_ci 0, 1968bf215546Sopenharmony_ci ureg->output[i].invariant); 1969bf215546Sopenharmony_ci } 1970bf215546Sopenharmony_ci } 1971bf215546Sopenharmony_ci } 1972bf215546Sopenharmony_ci 1973bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_samplers; i++) { 1974bf215546Sopenharmony_ci emit_decl_range( ureg, 1975bf215546Sopenharmony_ci TGSI_FILE_SAMPLER, 1976bf215546Sopenharmony_ci ureg->sampler[i].Index, 1 ); 1977bf215546Sopenharmony_ci } 1978bf215546Sopenharmony_ci 1979bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_sampler_views; i++) { 1980bf215546Sopenharmony_ci emit_decl_sampler_view(ureg, 1981bf215546Sopenharmony_ci ureg->sampler_view[i].index, 1982bf215546Sopenharmony_ci ureg->sampler_view[i].target, 1983bf215546Sopenharmony_ci ureg->sampler_view[i].return_type_x, 1984bf215546Sopenharmony_ci ureg->sampler_view[i].return_type_y, 1985bf215546Sopenharmony_ci ureg->sampler_view[i].return_type_z, 1986bf215546Sopenharmony_ci ureg->sampler_view[i].return_type_w); 1987bf215546Sopenharmony_ci } 1988bf215546Sopenharmony_ci 1989bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_images; i++) { 1990bf215546Sopenharmony_ci emit_decl_image(ureg, 1991bf215546Sopenharmony_ci ureg->image[i].index, 1992bf215546Sopenharmony_ci ureg->image[i].target, 1993bf215546Sopenharmony_ci ureg->image[i].format, 1994bf215546Sopenharmony_ci ureg->image[i].wr, 1995bf215546Sopenharmony_ci ureg->image[i].raw); 1996bf215546Sopenharmony_ci } 1997bf215546Sopenharmony_ci 1998bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_buffers; i++) { 1999bf215546Sopenharmony_ci emit_decl_buffer(ureg, ureg->buffer[i].index, ureg->buffer[i].atomic); 2000bf215546Sopenharmony_ci } 2001bf215546Sopenharmony_ci 2002bf215546Sopenharmony_ci for (i = 0; i < TGSI_MEMORY_TYPE_COUNT; i++) { 2003bf215546Sopenharmony_ci if (ureg->use_memory[i]) 2004bf215546Sopenharmony_ci emit_decl_memory(ureg, i); 2005bf215546Sopenharmony_ci } 2006bf215546Sopenharmony_ci 2007bf215546Sopenharmony_ci for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { 2008bf215546Sopenharmony_ci struct const_decl *decl = &ureg->const_decls[i]; 2009bf215546Sopenharmony_ci 2010bf215546Sopenharmony_ci if (decl->nr_constant_ranges) { 2011bf215546Sopenharmony_ci uint j; 2012bf215546Sopenharmony_ci 2013bf215546Sopenharmony_ci for (j = 0; j < decl->nr_constant_ranges; j++) { 2014bf215546Sopenharmony_ci emit_decl_range2D(ureg, 2015bf215546Sopenharmony_ci TGSI_FILE_CONSTANT, 2016bf215546Sopenharmony_ci decl->constant_range[j].first, 2017bf215546Sopenharmony_ci decl->constant_range[j].last, 2018bf215546Sopenharmony_ci i); 2019bf215546Sopenharmony_ci } 2020bf215546Sopenharmony_ci } 2021bf215546Sopenharmony_ci } 2022bf215546Sopenharmony_ci 2023bf215546Sopenharmony_ci for (i = 0; i < PIPE_MAX_HW_ATOMIC_BUFFERS; i++) { 2024bf215546Sopenharmony_ci struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[i]; 2025bf215546Sopenharmony_ci 2026bf215546Sopenharmony_ci if (decl->nr_hw_atomic_ranges) { 2027bf215546Sopenharmony_ci uint j; 2028bf215546Sopenharmony_ci 2029bf215546Sopenharmony_ci /* GLSL-to-TGSI generated HW atomic counters in order, and r600 depends 2030bf215546Sopenharmony_ci * on it. 2031bf215546Sopenharmony_ci */ 2032bf215546Sopenharmony_ci qsort(decl->hw_atomic_range, decl->nr_hw_atomic_ranges, sizeof(struct hw_atomic_decl_range), atomic_decl_range_sort); 2033bf215546Sopenharmony_ci 2034bf215546Sopenharmony_ci for (j = 0; j < decl->nr_hw_atomic_ranges; j++) { 2035bf215546Sopenharmony_ci emit_decl_atomic_2d(ureg, 2036bf215546Sopenharmony_ci decl->hw_atomic_range[j].first, 2037bf215546Sopenharmony_ci decl->hw_atomic_range[j].last, 2038bf215546Sopenharmony_ci i, 2039bf215546Sopenharmony_ci decl->hw_atomic_range[j].array_id); 2040bf215546Sopenharmony_ci } 2041bf215546Sopenharmony_ci } 2042bf215546Sopenharmony_ci } 2043bf215546Sopenharmony_ci 2044bf215546Sopenharmony_ci if (ureg->nr_temps) { 2045bf215546Sopenharmony_ci unsigned array = 0; 2046bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_temps;) { 2047bf215546Sopenharmony_ci boolean local = util_bitmask_get(ureg->local_temps, i); 2048bf215546Sopenharmony_ci unsigned first = i; 2049bf215546Sopenharmony_ci i = util_bitmask_get_next_index(ureg->decl_temps, i + 1); 2050bf215546Sopenharmony_ci if (i == UTIL_BITMASK_INVALID_INDEX) 2051bf215546Sopenharmony_ci i = ureg->nr_temps; 2052bf215546Sopenharmony_ci 2053bf215546Sopenharmony_ci if (array < ureg->nr_array_temps && ureg->array_temps[array] == first) 2054bf215546Sopenharmony_ci emit_decl_temps( ureg, first, i - 1, local, ++array ); 2055bf215546Sopenharmony_ci else 2056bf215546Sopenharmony_ci emit_decl_temps( ureg, first, i - 1, local, 0 ); 2057bf215546Sopenharmony_ci } 2058bf215546Sopenharmony_ci } 2059bf215546Sopenharmony_ci 2060bf215546Sopenharmony_ci if (ureg->nr_addrs) { 2061bf215546Sopenharmony_ci emit_decl_range( ureg, 2062bf215546Sopenharmony_ci TGSI_FILE_ADDRESS, 2063bf215546Sopenharmony_ci 0, ureg->nr_addrs ); 2064bf215546Sopenharmony_ci } 2065bf215546Sopenharmony_ci 2066bf215546Sopenharmony_ci for (i = 0; i < ureg->nr_immediates; i++) { 2067bf215546Sopenharmony_ci emit_immediate( ureg, 2068bf215546Sopenharmony_ci ureg->immediate[i].value.u, 2069bf215546Sopenharmony_ci ureg->immediate[i].type ); 2070bf215546Sopenharmony_ci } 2071bf215546Sopenharmony_ci} 2072bf215546Sopenharmony_ci 2073bf215546Sopenharmony_ci/* Append the instruction tokens onto the declarations to build a 2074bf215546Sopenharmony_ci * contiguous stream suitable to send to the driver. 2075bf215546Sopenharmony_ci */ 2076bf215546Sopenharmony_cistatic void copy_instructions( struct ureg_program *ureg ) 2077bf215546Sopenharmony_ci{ 2078bf215546Sopenharmony_ci unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count; 2079bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens( ureg, 2080bf215546Sopenharmony_ci DOMAIN_DECL, 2081bf215546Sopenharmony_ci nr_tokens ); 2082bf215546Sopenharmony_ci 2083bf215546Sopenharmony_ci memcpy(out, 2084bf215546Sopenharmony_ci ureg->domain[DOMAIN_INSN].tokens, 2085bf215546Sopenharmony_ci nr_tokens * sizeof out[0] ); 2086bf215546Sopenharmony_ci} 2087bf215546Sopenharmony_ci 2088bf215546Sopenharmony_ci 2089bf215546Sopenharmony_cistatic void 2090bf215546Sopenharmony_cifixup_header_size(struct ureg_program *ureg) 2091bf215546Sopenharmony_ci{ 2092bf215546Sopenharmony_ci union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 0 ); 2093bf215546Sopenharmony_ci 2094bf215546Sopenharmony_ci out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 2; 2095bf215546Sopenharmony_ci} 2096bf215546Sopenharmony_ci 2097bf215546Sopenharmony_ci 2098bf215546Sopenharmony_cistatic void 2099bf215546Sopenharmony_ciemit_header( struct ureg_program *ureg ) 2100bf215546Sopenharmony_ci{ 2101bf215546Sopenharmony_ci union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 ); 2102bf215546Sopenharmony_ci 2103bf215546Sopenharmony_ci out[0].header.HeaderSize = 2; 2104bf215546Sopenharmony_ci out[0].header.BodySize = 0; 2105bf215546Sopenharmony_ci 2106bf215546Sopenharmony_ci out[1].processor.Processor = ureg->processor; 2107bf215546Sopenharmony_ci out[1].processor.Padding = 0; 2108bf215546Sopenharmony_ci} 2109bf215546Sopenharmony_ci 2110bf215546Sopenharmony_ci 2111bf215546Sopenharmony_ciconst struct tgsi_token *ureg_finalize( struct ureg_program *ureg ) 2112bf215546Sopenharmony_ci{ 2113bf215546Sopenharmony_ci const struct tgsi_token *tokens; 2114bf215546Sopenharmony_ci 2115bf215546Sopenharmony_ci switch (ureg->processor) { 2116bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 2117bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 2118bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_NEXT_SHADER, 2119bf215546Sopenharmony_ci ureg->next_shader_processor == -1 ? 2120bf215546Sopenharmony_ci PIPE_SHADER_FRAGMENT : 2121bf215546Sopenharmony_ci ureg->next_shader_processor); 2122bf215546Sopenharmony_ci break; 2123bf215546Sopenharmony_ci default: 2124bf215546Sopenharmony_ci ; /* nothing */ 2125bf215546Sopenharmony_ci } 2126bf215546Sopenharmony_ci 2127bf215546Sopenharmony_ci emit_header( ureg ); 2128bf215546Sopenharmony_ci emit_decls( ureg ); 2129bf215546Sopenharmony_ci copy_instructions( ureg ); 2130bf215546Sopenharmony_ci fixup_header_size( ureg ); 2131bf215546Sopenharmony_ci 2132bf215546Sopenharmony_ci if (ureg->domain[0].tokens == error_tokens || 2133bf215546Sopenharmony_ci ureg->domain[1].tokens == error_tokens) { 2134bf215546Sopenharmony_ci debug_printf("%s: error in generated shader\n", __FUNCTION__); 2135bf215546Sopenharmony_ci assert(0); 2136bf215546Sopenharmony_ci return NULL; 2137bf215546Sopenharmony_ci } 2138bf215546Sopenharmony_ci 2139bf215546Sopenharmony_ci tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token; 2140bf215546Sopenharmony_ci 2141bf215546Sopenharmony_ci if (0) { 2142bf215546Sopenharmony_ci debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__, 2143bf215546Sopenharmony_ci ureg->domain[DOMAIN_DECL].count); 2144bf215546Sopenharmony_ci tgsi_dump( tokens, 0 ); 2145bf215546Sopenharmony_ci } 2146bf215546Sopenharmony_ci 2147bf215546Sopenharmony_ci#if DEBUG 2148bf215546Sopenharmony_ci /* tgsi_sanity doesn't seem to return if there are too many constants. */ 2149bf215546Sopenharmony_ci bool too_many_constants = false; 2150bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(ureg->const_decls); i++) { 2151bf215546Sopenharmony_ci for (unsigned j = 0; j < ureg->const_decls[i].nr_constant_ranges; j++) { 2152bf215546Sopenharmony_ci if (ureg->const_decls[i].constant_range[j].last > 4096) { 2153bf215546Sopenharmony_ci too_many_constants = true; 2154bf215546Sopenharmony_ci break; 2155bf215546Sopenharmony_ci } 2156bf215546Sopenharmony_ci } 2157bf215546Sopenharmony_ci } 2158bf215546Sopenharmony_ci 2159bf215546Sopenharmony_ci if (tokens && !too_many_constants && !tgsi_sanity_check(tokens)) { 2160bf215546Sopenharmony_ci debug_printf("tgsi_ureg.c, sanity check failed on generated tokens:\n"); 2161bf215546Sopenharmony_ci tgsi_dump(tokens, 0); 2162bf215546Sopenharmony_ci assert(0); 2163bf215546Sopenharmony_ci } 2164bf215546Sopenharmony_ci#endif 2165bf215546Sopenharmony_ci 2166bf215546Sopenharmony_ci 2167bf215546Sopenharmony_ci return tokens; 2168bf215546Sopenharmony_ci} 2169bf215546Sopenharmony_ci 2170bf215546Sopenharmony_ci 2171bf215546Sopenharmony_civoid *ureg_create_shader( struct ureg_program *ureg, 2172bf215546Sopenharmony_ci struct pipe_context *pipe, 2173bf215546Sopenharmony_ci const struct pipe_stream_output_info *so ) 2174bf215546Sopenharmony_ci{ 2175bf215546Sopenharmony_ci struct pipe_shader_state state = {0}; 2176bf215546Sopenharmony_ci 2177bf215546Sopenharmony_ci pipe_shader_state_from_tgsi(&state, ureg_finalize(ureg)); 2178bf215546Sopenharmony_ci if(!state.tokens) 2179bf215546Sopenharmony_ci return NULL; 2180bf215546Sopenharmony_ci 2181bf215546Sopenharmony_ci if (so) 2182bf215546Sopenharmony_ci state.stream_output = *so; 2183bf215546Sopenharmony_ci 2184bf215546Sopenharmony_ci switch (ureg->processor) { 2185bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 2186bf215546Sopenharmony_ci return pipe->create_vs_state(pipe, &state); 2187bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 2188bf215546Sopenharmony_ci return pipe->create_tcs_state(pipe, &state); 2189bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 2190bf215546Sopenharmony_ci return pipe->create_tes_state(pipe, &state); 2191bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 2192bf215546Sopenharmony_ci return pipe->create_gs_state(pipe, &state); 2193bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 2194bf215546Sopenharmony_ci return pipe->create_fs_state(pipe, &state); 2195bf215546Sopenharmony_ci default: 2196bf215546Sopenharmony_ci return NULL; 2197bf215546Sopenharmony_ci } 2198bf215546Sopenharmony_ci} 2199bf215546Sopenharmony_ci 2200bf215546Sopenharmony_ci 2201bf215546Sopenharmony_ciconst struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg, 2202bf215546Sopenharmony_ci unsigned *nr_tokens ) 2203bf215546Sopenharmony_ci{ 2204bf215546Sopenharmony_ci const struct tgsi_token *tokens; 2205bf215546Sopenharmony_ci 2206bf215546Sopenharmony_ci ureg_finalize(ureg); 2207bf215546Sopenharmony_ci 2208bf215546Sopenharmony_ci tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token; 2209bf215546Sopenharmony_ci 2210bf215546Sopenharmony_ci if (nr_tokens) 2211bf215546Sopenharmony_ci *nr_tokens = ureg->domain[DOMAIN_DECL].count; 2212bf215546Sopenharmony_ci 2213bf215546Sopenharmony_ci ureg->domain[DOMAIN_DECL].tokens = NULL; 2214bf215546Sopenharmony_ci ureg->domain[DOMAIN_DECL].size = 0; 2215bf215546Sopenharmony_ci ureg->domain[DOMAIN_DECL].order = 0; 2216bf215546Sopenharmony_ci ureg->domain[DOMAIN_DECL].count = 0; 2217bf215546Sopenharmony_ci 2218bf215546Sopenharmony_ci return tokens; 2219bf215546Sopenharmony_ci} 2220bf215546Sopenharmony_ci 2221bf215546Sopenharmony_ci 2222bf215546Sopenharmony_civoid ureg_free_tokens( const struct tgsi_token *tokens ) 2223bf215546Sopenharmony_ci{ 2224bf215546Sopenharmony_ci FREE((struct tgsi_token *)tokens); 2225bf215546Sopenharmony_ci} 2226bf215546Sopenharmony_ci 2227bf215546Sopenharmony_ci 2228bf215546Sopenharmony_cistruct ureg_program * 2229bf215546Sopenharmony_ciureg_create(enum pipe_shader_type processor) 2230bf215546Sopenharmony_ci{ 2231bf215546Sopenharmony_ci return ureg_create_with_screen(processor, NULL); 2232bf215546Sopenharmony_ci} 2233bf215546Sopenharmony_ci 2234bf215546Sopenharmony_ci 2235bf215546Sopenharmony_cistruct ureg_program * 2236bf215546Sopenharmony_ciureg_create_with_screen(enum pipe_shader_type processor, 2237bf215546Sopenharmony_ci struct pipe_screen *screen) 2238bf215546Sopenharmony_ci{ 2239bf215546Sopenharmony_ci uint i; 2240bf215546Sopenharmony_ci struct ureg_program *ureg = CALLOC_STRUCT( ureg_program ); 2241bf215546Sopenharmony_ci if (!ureg) 2242bf215546Sopenharmony_ci goto no_ureg; 2243bf215546Sopenharmony_ci 2244bf215546Sopenharmony_ci ureg->processor = processor; 2245bf215546Sopenharmony_ci ureg->supports_any_inout_decl_range = 2246bf215546Sopenharmony_ci screen && 2247bf215546Sopenharmony_ci screen->get_shader_param(screen, processor, 2248bf215546Sopenharmony_ci PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE) != 0; 2249bf215546Sopenharmony_ci ureg->next_shader_processor = -1; 2250bf215546Sopenharmony_ci 2251bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ureg->properties); i++) 2252bf215546Sopenharmony_ci ureg->properties[i] = ~0; 2253bf215546Sopenharmony_ci 2254bf215546Sopenharmony_ci ureg->free_temps = util_bitmask_create(); 2255bf215546Sopenharmony_ci if (ureg->free_temps == NULL) 2256bf215546Sopenharmony_ci goto no_free_temps; 2257bf215546Sopenharmony_ci 2258bf215546Sopenharmony_ci ureg->local_temps = util_bitmask_create(); 2259bf215546Sopenharmony_ci if (ureg->local_temps == NULL) 2260bf215546Sopenharmony_ci goto no_local_temps; 2261bf215546Sopenharmony_ci 2262bf215546Sopenharmony_ci ureg->decl_temps = util_bitmask_create(); 2263bf215546Sopenharmony_ci if (ureg->decl_temps == NULL) 2264bf215546Sopenharmony_ci goto no_decl_temps; 2265bf215546Sopenharmony_ci 2266bf215546Sopenharmony_ci return ureg; 2267bf215546Sopenharmony_ci 2268bf215546Sopenharmony_cino_decl_temps: 2269bf215546Sopenharmony_ci util_bitmask_destroy(ureg->local_temps); 2270bf215546Sopenharmony_cino_local_temps: 2271bf215546Sopenharmony_ci util_bitmask_destroy(ureg->free_temps); 2272bf215546Sopenharmony_cino_free_temps: 2273bf215546Sopenharmony_ci FREE(ureg); 2274bf215546Sopenharmony_cino_ureg: 2275bf215546Sopenharmony_ci return NULL; 2276bf215546Sopenharmony_ci} 2277bf215546Sopenharmony_ci 2278bf215546Sopenharmony_ci 2279bf215546Sopenharmony_civoid 2280bf215546Sopenharmony_ciureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor) 2281bf215546Sopenharmony_ci{ 2282bf215546Sopenharmony_ci ureg->next_shader_processor = processor; 2283bf215546Sopenharmony_ci} 2284bf215546Sopenharmony_ci 2285bf215546Sopenharmony_ci 2286bf215546Sopenharmony_ciunsigned 2287bf215546Sopenharmony_ciureg_get_nr_outputs( const struct ureg_program *ureg ) 2288bf215546Sopenharmony_ci{ 2289bf215546Sopenharmony_ci if (!ureg) 2290bf215546Sopenharmony_ci return 0; 2291bf215546Sopenharmony_ci return ureg->nr_outputs; 2292bf215546Sopenharmony_ci} 2293bf215546Sopenharmony_ci 2294bf215546Sopenharmony_cistatic void 2295bf215546Sopenharmony_ciureg_setup_clipdist_info(struct ureg_program *ureg, 2296bf215546Sopenharmony_ci const struct shader_info *info) 2297bf215546Sopenharmony_ci{ 2298bf215546Sopenharmony_ci if (info->clip_distance_array_size) 2299bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED, 2300bf215546Sopenharmony_ci info->clip_distance_array_size); 2301bf215546Sopenharmony_ci if (info->cull_distance_array_size) 2302bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED, 2303bf215546Sopenharmony_ci info->cull_distance_array_size); 2304bf215546Sopenharmony_ci} 2305bf215546Sopenharmony_ci 2306bf215546Sopenharmony_cistatic void 2307bf215546Sopenharmony_ciureg_setup_tess_ctrl_shader(struct ureg_program *ureg, 2308bf215546Sopenharmony_ci const struct shader_info *info) 2309bf215546Sopenharmony_ci{ 2310bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT, 2311bf215546Sopenharmony_ci info->tess.tcs_vertices_out); 2312bf215546Sopenharmony_ci} 2313bf215546Sopenharmony_ci 2314bf215546Sopenharmony_cistatic void 2315bf215546Sopenharmony_ciureg_setup_tess_eval_shader(struct ureg_program *ureg, 2316bf215546Sopenharmony_ci const struct shader_info *info) 2317bf215546Sopenharmony_ci{ 2318bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, u_tess_prim_from_shader(info->tess._primitive_mode)); 2319bf215546Sopenharmony_ci 2320bf215546Sopenharmony_ci STATIC_ASSERT((TESS_SPACING_EQUAL + 1) % 3 == PIPE_TESS_SPACING_EQUAL); 2321bf215546Sopenharmony_ci STATIC_ASSERT((TESS_SPACING_FRACTIONAL_ODD + 1) % 3 == 2322bf215546Sopenharmony_ci PIPE_TESS_SPACING_FRACTIONAL_ODD); 2323bf215546Sopenharmony_ci STATIC_ASSERT((TESS_SPACING_FRACTIONAL_EVEN + 1) % 3 == 2324bf215546Sopenharmony_ci PIPE_TESS_SPACING_FRACTIONAL_EVEN); 2325bf215546Sopenharmony_ci 2326bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_TES_SPACING, 2327bf215546Sopenharmony_ci (info->tess.spacing + 1) % 3); 2328bf215546Sopenharmony_ci 2329bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_TES_VERTEX_ORDER_CW, 2330bf215546Sopenharmony_ci !info->tess.ccw); 2331bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_TES_POINT_MODE, 2332bf215546Sopenharmony_ci info->tess.point_mode); 2333bf215546Sopenharmony_ci} 2334bf215546Sopenharmony_ci 2335bf215546Sopenharmony_cistatic void 2336bf215546Sopenharmony_ciureg_setup_geometry_shader(struct ureg_program *ureg, 2337bf215546Sopenharmony_ci const struct shader_info *info) 2338bf215546Sopenharmony_ci{ 2339bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, 2340bf215546Sopenharmony_ci info->gs.input_primitive); 2341bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, 2342bf215546Sopenharmony_ci info->gs.output_primitive); 2343bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 2344bf215546Sopenharmony_ci info->gs.vertices_out); 2345bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, 2346bf215546Sopenharmony_ci info->gs.invocations); 2347bf215546Sopenharmony_ci} 2348bf215546Sopenharmony_ci 2349bf215546Sopenharmony_cistatic void 2350bf215546Sopenharmony_ciureg_setup_fragment_shader(struct ureg_program *ureg, 2351bf215546Sopenharmony_ci const struct shader_info *info) 2352bf215546Sopenharmony_ci{ 2353bf215546Sopenharmony_ci if (info->fs.early_fragment_tests || info->fs.post_depth_coverage) { 2354bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL, 1); 2355bf215546Sopenharmony_ci 2356bf215546Sopenharmony_ci if (info->fs.post_depth_coverage) 2357bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_FS_POST_DEPTH_COVERAGE, 1); 2358bf215546Sopenharmony_ci } 2359bf215546Sopenharmony_ci 2360bf215546Sopenharmony_ci if (info->fs.depth_layout != FRAG_DEPTH_LAYOUT_NONE) { 2361bf215546Sopenharmony_ci switch (info->fs.depth_layout) { 2362bf215546Sopenharmony_ci case FRAG_DEPTH_LAYOUT_ANY: 2363bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT, 2364bf215546Sopenharmony_ci TGSI_FS_DEPTH_LAYOUT_ANY); 2365bf215546Sopenharmony_ci break; 2366bf215546Sopenharmony_ci case FRAG_DEPTH_LAYOUT_GREATER: 2367bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT, 2368bf215546Sopenharmony_ci TGSI_FS_DEPTH_LAYOUT_GREATER); 2369bf215546Sopenharmony_ci break; 2370bf215546Sopenharmony_ci case FRAG_DEPTH_LAYOUT_LESS: 2371bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT, 2372bf215546Sopenharmony_ci TGSI_FS_DEPTH_LAYOUT_LESS); 2373bf215546Sopenharmony_ci break; 2374bf215546Sopenharmony_ci case FRAG_DEPTH_LAYOUT_UNCHANGED: 2375bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT, 2376bf215546Sopenharmony_ci TGSI_FS_DEPTH_LAYOUT_UNCHANGED); 2377bf215546Sopenharmony_ci break; 2378bf215546Sopenharmony_ci default: 2379bf215546Sopenharmony_ci assert(0); 2380bf215546Sopenharmony_ci } 2381bf215546Sopenharmony_ci } 2382bf215546Sopenharmony_ci 2383bf215546Sopenharmony_ci if (info->fs.advanced_blend_modes) { 2384bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_FS_BLEND_EQUATION_ADVANCED, 2385bf215546Sopenharmony_ci info->fs.advanced_blend_modes); 2386bf215546Sopenharmony_ci } 2387bf215546Sopenharmony_ci} 2388bf215546Sopenharmony_ci 2389bf215546Sopenharmony_cistatic void 2390bf215546Sopenharmony_ciureg_setup_compute_shader(struct ureg_program *ureg, 2391bf215546Sopenharmony_ci const struct shader_info *info) 2392bf215546Sopenharmony_ci{ 2393bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH, 2394bf215546Sopenharmony_ci info->workgroup_size[0]); 2395bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT, 2396bf215546Sopenharmony_ci info->workgroup_size[1]); 2397bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH, 2398bf215546Sopenharmony_ci info->workgroup_size[2]); 2399bf215546Sopenharmony_ci 2400bf215546Sopenharmony_ci if (info->shared_size) 2401bf215546Sopenharmony_ci ureg_DECL_memory(ureg, TGSI_MEMORY_TYPE_SHARED); 2402bf215546Sopenharmony_ci} 2403bf215546Sopenharmony_ci 2404bf215546Sopenharmony_civoid 2405bf215546Sopenharmony_ciureg_setup_shader_info(struct ureg_program *ureg, 2406bf215546Sopenharmony_ci const struct shader_info *info) 2407bf215546Sopenharmony_ci{ 2408bf215546Sopenharmony_ci if (info->layer_viewport_relative) 2409bf215546Sopenharmony_ci ureg_property(ureg, TGSI_PROPERTY_LAYER_VIEWPORT_RELATIVE, 1); 2410bf215546Sopenharmony_ci 2411bf215546Sopenharmony_ci switch (info->stage) { 2412bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 2413bf215546Sopenharmony_ci ureg_setup_clipdist_info(ureg, info); 2414bf215546Sopenharmony_ci ureg_set_next_shader_processor(ureg, pipe_shader_type_from_mesa(info->next_stage)); 2415bf215546Sopenharmony_ci break; 2416bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 2417bf215546Sopenharmony_ci ureg_setup_tess_ctrl_shader(ureg, info); 2418bf215546Sopenharmony_ci break; 2419bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 2420bf215546Sopenharmony_ci ureg_setup_tess_eval_shader(ureg, info); 2421bf215546Sopenharmony_ci ureg_setup_clipdist_info(ureg, info); 2422bf215546Sopenharmony_ci ureg_set_next_shader_processor(ureg, pipe_shader_type_from_mesa(info->next_stage)); 2423bf215546Sopenharmony_ci break; 2424bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 2425bf215546Sopenharmony_ci ureg_setup_geometry_shader(ureg, info); 2426bf215546Sopenharmony_ci ureg_setup_clipdist_info(ureg, info); 2427bf215546Sopenharmony_ci break; 2428bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 2429bf215546Sopenharmony_ci ureg_setup_fragment_shader(ureg, info); 2430bf215546Sopenharmony_ci break; 2431bf215546Sopenharmony_ci case MESA_SHADER_COMPUTE: 2432bf215546Sopenharmony_ci ureg_setup_compute_shader(ureg, info); 2433bf215546Sopenharmony_ci break; 2434bf215546Sopenharmony_ci default: 2435bf215546Sopenharmony_ci break; 2436bf215546Sopenharmony_ci } 2437bf215546Sopenharmony_ci} 2438bf215546Sopenharmony_ci 2439bf215546Sopenharmony_ci 2440bf215546Sopenharmony_civoid ureg_destroy( struct ureg_program *ureg ) 2441bf215546Sopenharmony_ci{ 2442bf215546Sopenharmony_ci unsigned i; 2443bf215546Sopenharmony_ci 2444bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ureg->domain); i++) { 2445bf215546Sopenharmony_ci if (ureg->domain[i].tokens && 2446bf215546Sopenharmony_ci ureg->domain[i].tokens != error_tokens) 2447bf215546Sopenharmony_ci FREE(ureg->domain[i].tokens); 2448bf215546Sopenharmony_ci } 2449bf215546Sopenharmony_ci 2450bf215546Sopenharmony_ci util_bitmask_destroy(ureg->free_temps); 2451bf215546Sopenharmony_ci util_bitmask_destroy(ureg->local_temps); 2452bf215546Sopenharmony_ci util_bitmask_destroy(ureg->decl_temps); 2453bf215546Sopenharmony_ci 2454bf215546Sopenharmony_ci FREE(ureg); 2455bf215546Sopenharmony_ci} 2456bf215546Sopenharmony_ci 2457bf215546Sopenharmony_civoid ureg_set_precise( struct ureg_program *ureg, bool precise ) 2458bf215546Sopenharmony_ci{ 2459bf215546Sopenharmony_ci ureg->precise = precise; 2460bf215546Sopenharmony_ci} 2461