1a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 2ce40e4726cf30196b87df387255c64ddc2a97638Christian König/* 3ce40e4726cf30196b87df387255c64ddc2a97638Christian König * Copyright 2012 Advanced Micro Devices, Inc. 4ce40e4726cf30196b87df387255c64ddc2a97638Christian König * 5ce40e4726cf30196b87df387255c64ddc2a97638Christian König * Permission is hereby granted, free of charge, to any person obtaining a 6ce40e4726cf30196b87df387255c64ddc2a97638Christian König * copy of this software and associated documentation files (the "Software"), 7ce40e4726cf30196b87df387255c64ddc2a97638Christian König * to deal in the Software without restriction, including without limitation 8ce40e4726cf30196b87df387255c64ddc2a97638Christian König * on the rights to use, copy, modify, merge, publish, distribute, sub 9ce40e4726cf30196b87df387255c64ddc2a97638Christian König * license, and/or sell copies of the Software, and to permit persons to whom 10ce40e4726cf30196b87df387255c64ddc2a97638Christian König * the Software is furnished to do so, subject to the following conditions: 11ce40e4726cf30196b87df387255c64ddc2a97638Christian König * 12ce40e4726cf30196b87df387255c64ddc2a97638Christian König * The above copyright notice and this permission notice (including the next 13ce40e4726cf30196b87df387255c64ddc2a97638Christian König * paragraph) shall be included in all copies or substantial portions of the 14ce40e4726cf30196b87df387255c64ddc2a97638Christian König * Software. 15ce40e4726cf30196b87df387255c64ddc2a97638Christian König * 16ce40e4726cf30196b87df387255c64ddc2a97638Christian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17ce40e4726cf30196b87df387255c64ddc2a97638Christian König * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18ce40e4726cf30196b87df387255c64ddc2a97638Christian König * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19ce40e4726cf30196b87df387255c64ddc2a97638Christian König * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20ce40e4726cf30196b87df387255c64ddc2a97638Christian König * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21ce40e4726cf30196b87df387255c64ddc2a97638Christian König * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22ce40e4726cf30196b87df387255c64ddc2a97638Christian König * USE OR OTHER DEALINGS IN THE SOFTWARE. 23ce40e4726cf30196b87df387255c64ddc2a97638Christian König * 24ce40e4726cf30196b87df387255c64ddc2a97638Christian König * Authors: 25ce40e4726cf30196b87df387255c64ddc2a97638Christian König * Tom Stellard <thomas.stellard@amd.com> 26ce40e4726cf30196b87df387255c64ddc2a97638Christian König * Michel Dänzer <michel.daenzer@amd.com> 27ce40e4726cf30196b87df387255c64ddc2a97638Christian König * Christian König <christian.koenig@amd.com> 28ce40e4726cf30196b87df387255c64ddc2a97638Christian König */ 29ce40e4726cf30196b87df387255c64ddc2a97638Christian König 30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_tgsi_action.h" 31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_const.h" 32c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer#include "gallivm/lp_bld_gather.h" 33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_intr.h" 34a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_tgsi.h" 35a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "radeon_llvm.h" 36509ddb0a0414cfc83102c463da542d95d83eabadTom Stellard#include "radeon_llvm_emit.h" 37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "tgsi/tgsi_info.h" 38a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "tgsi/tgsi_parse.h" 39a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "tgsi/tgsi_scan.h" 40a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "tgsi/tgsi_dump.h" 41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "radeonsi_pipe.h" 43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "radeonsi_shader.h" 44f67fae0e43fa0909b57b8a07858d37caecd5cbb1Christian König#include "si_state.h" 45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "sid.h" 46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 47a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <assert.h> 48a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <errno.h> 49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <stdio.h> 50a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 51a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* 52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic ps_remap_inputs( 53a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct tgsi_llvm_context * tl_ctx, 54a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned tgsi_index, 55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned tgsi_chan) 56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 57a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard : 58a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 59a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct si_input 61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct list_head head; 63a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned tgsi_index; 64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned tgsi_chan; 65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned order; 66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}; 67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard*/ 68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 69a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct si_shader_context 71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 72a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct radeon_llvm_context radeon_bld; 73a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_context *rctx; 74a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct tgsi_parse_context parse; 75a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct tgsi_token * tokens; 76a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct si_pipe_shader *shader; 77a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned type; /* TGSI_PROCESSOR_* specifies the type of shader. */ 78a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* unsigned num_inputs; */ 79a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* struct list_head inputs; */ 80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* unsigned * input_mappings *//* From TGSI to SI hw */ 81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* struct tgsi_shader_info info;*/ 82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}; 83a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 84a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct si_shader_context * si_shader_context( 85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_tgsi_context * bld_base) 86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return (struct si_shader_context *)bld_base; 88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define PERSPECTIVE_BASE 0 92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define LINEAR_BASE 9 93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define SAMPLE_OFFSET 0 95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define CENTER_OFFSET 2 96a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define CENTROID_OFSET 4 97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 98a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define USE_SGPR_MAX_SUFFIX_LEN 5 99467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard#define CONST_ADDR_SPACE 2 10089ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard#define USER_SGPR_ADDR_SPACE 8 101a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 102a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardenum sgpr_type { 103467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard SGPR_CONST_PTR_F32, 104467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard SGPR_CONST_PTR_V4I32, 105467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard SGPR_CONST_PTR_V8I32, 106a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard SGPR_I32, 107467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard SGPR_I64 108a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}; 109a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 110467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard/** 111467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * Build an LLVM bytecode indexed load using LLVMBuildGEP + LLVMBuildLoad 112467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * 113467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * @param offset The offset parameter specifies the number of 114467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * elements to offset, not the number of bytes or dwords. An element is the 115467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * the type pointed to by the base_ptr parameter (e.g. int is the element of 116467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * an int* pointer) 117467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * 118467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * When LLVM lowers the load instruction, it will convert the element offset 119467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * into a dword offset automatically. 120467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard * 121467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard */ 122467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellardstatic LLVMValueRef build_indexed_load( 123467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard struct gallivm_state * gallivm, 124467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard LLVMValueRef base_ptr, 125467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard LLVMValueRef offset) 126467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard{ 127467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard LLVMValueRef computed_ptr = LLVMBuildGEP( 128467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard gallivm->builder, base_ptr, &offset, 1, ""); 129467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard 130467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard return LLVMBuildLoad(gallivm->builder, computed_ptr, ""); 131467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard} 132467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard 13389ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard/** 13489ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * Load a value stored in one of the user SGPRs 13589ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * 13689ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * @param sgpr This is the sgpr to load the value from. If you need to load a 13789ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * value that is stored in consecutive SGPR registers (e.g. a 64-bit pointer), 13889ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * then you should pass the index of the first SGPR that holds the value. For 13989ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * example, if you want to load a pointer that is stored in SGPRs 2 and 3, then 14089ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * use pass 2 for the sgpr parameter. 14189ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * 14289ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * The value of the sgpr parameter must also be aligned to the width of the type 14389ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * being loaded, so that the sgpr parameter is divisible by the dword width of the 14489ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * type. For example, if the value being loaded is two dwords wide, then the sgpr 14589ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard * parameter must be divisible by two. 146467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard */ 147a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic LLVMValueRef use_sgpr( 148a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct gallivm_state * gallivm, 149a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard enum sgpr_type type, 150a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned sgpr) 151a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 152a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef sgpr_index; 153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMTypeRef ret_type; 15489ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard LLVMValueRef ptr; 155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 156a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard sgpr_index = lp_build_const_int32(gallivm, sgpr); 157a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 158467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard switch (type) { 159467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard case SGPR_CONST_PTR_F32: 16089ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard assert(sgpr % 2 == 0); 161467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard ret_type = LLVMFloatTypeInContext(gallivm->context); 162467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard ret_type = LLVMPointerType(ret_type, CONST_ADDR_SPACE); 16389ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard break; 16489ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard 165467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard case SGPR_I32: 166a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ret_type = LLVMInt32TypeInContext(gallivm->context); 16789ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard break; 16889ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard 169467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard case SGPR_I64: 17089ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard assert(sgpr % 2 == 0); 171467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard ret_type= LLVMInt64TypeInContext(gallivm->context); 17289ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard break; 17389ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard 174467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard case SGPR_CONST_PTR_V4I32: 17589ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard assert(sgpr % 2 == 0); 176a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ret_type = LLVMInt32TypeInContext(gallivm->context); 177a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ret_type = LLVMVectorType(ret_type, 4); 178467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard ret_type = LLVMPointerType(ret_type, CONST_ADDR_SPACE); 17989ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard break; 18089ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard 181467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard case SGPR_CONST_PTR_V8I32: 18289ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard assert(sgpr % 2 == 0); 183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ret_type = LLVMInt32TypeInContext(gallivm->context); 184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ret_type = LLVMVectorType(ret_type, 8); 185467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard ret_type = LLVMPointerType(ret_type, CONST_ADDR_SPACE); 18689ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard break; 18789ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard 188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard assert(!"Unsupported SGPR type in use_sgpr()"); 190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 19289ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard 19389ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard ret_type = LLVMPointerType(ret_type, USER_SGPR_ADDR_SPACE); 19489ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard ptr = LLVMBuildIntToPtr(gallivm->builder, sgpr_index, ret_type, ""); 19589ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard return LLVMBuildLoad(gallivm->builder, ptr, ""); 196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void declare_input_vs( 199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct si_shader_context * si_shader_ctx, 200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned input_index, 201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct tgsi_full_declaration *decl) 202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef t_list_ptr; 204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef t_offset; 205467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard LLVMValueRef t_list; 206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef attribute_offset; 207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef buffer_index_reg; 208467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard LLVMValueRef args[3]; 209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMTypeRef vec4_type; 210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef input; 211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_context * uint = &si_shader_ctx->radeon_bld.soa.bld_base.uint_bld; 212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_context * base = &si_shader_ctx->radeon_bld.soa.bld_base.base; 213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_context *rctx = si_shader_ctx->rctx; 214b15e3ae5b423dd8846a35500c0274d1d74f6b836Christian König //struct pipe_vertex_element *velem = &rctx->vertex_elements->elements[input_index]; 215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned chan; 216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 217467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard /* Load the T list */ 218a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: Communicate with the rest of the driver about which SGPR the T# 2199918fbd0268601b4dcd7c07c883733c959d78f9eMichel Dänzer * list pointer is going to be stored in. Hard code to SGPR[6:7] for 220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * now */ 22189ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard t_list_ptr = use_sgpr(base->gallivm, SGPR_CONST_PTR_V4I32, 6); 222467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard 223b15e3ae5b423dd8846a35500c0274d1d74f6b836Christian König t_offset = lp_build_const_int32(base->gallivm, input_index); 224a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 225467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard t_list = build_indexed_load(base->gallivm, t_list_ptr, t_offset); 226467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard 227467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard /* Build the attribute offset */ 228b15e3ae5b423dd8846a35500c0274d1d74f6b836Christian König attribute_offset = lp_build_const_int32(base->gallivm, 0); 229a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 230a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Load the buffer index is always, which is always stored in VGPR0 231a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * for Vertex Shaders */ 23240c41fe890e53d99afb4e2c3fbf10043081edd9eTom Stellard buffer_index_reg = build_intrinsic(base->gallivm->builder, 23340c41fe890e53d99afb4e2c3fbf10043081edd9eTom Stellard "llvm.SI.vs.load.buffer.index", uint->elem_type, NULL, 0, 23440c41fe890e53d99afb4e2c3fbf10043081edd9eTom Stellard LLVMReadNoneAttribute); 235a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 236a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard vec4_type = LLVMVectorType(base->elem_type, 4); 237467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard args[0] = t_list; 238467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard args[1] = attribute_offset; 239467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard args[2] = buffer_index_reg; 240a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard input = lp_build_intrinsic(base->gallivm->builder, 241467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard "llvm.SI.vs.load.input", vec4_type, args, 3); 242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 243a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Break up the vec4 into individual components */ 244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard for (chan = 0; chan < 4; chan++) { 245a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef llvm_chan = lp_build_const_int32(base->gallivm, chan); 246a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: Use a helper function for this. There is one in 247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * tgsi_llvm.c. */ 248a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard si_shader_ctx->radeon_bld.inputs[radeon_llvm_reg_index_soa(input_index, chan)] = 249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMBuildExtractElement(base->gallivm->builder, 250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard input, llvm_chan, ""); 251a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 252a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 253a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void declare_input_fs( 255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct si_shader_context * si_shader_ctx, 256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned input_index, 257a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct tgsi_full_declaration *decl) 258a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 259a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const char * intr_name; 260a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned chan; 261a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_context * base = 262a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard &si_shader_ctx->radeon_bld.soa.bld_base.base; 263a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct gallivm_state * gallivm = base->gallivm; 264a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 265a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* This value is: 266a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * [15:0] NewPrimMask (Bit mask for each quad. It is set it the 267a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * quad begins a new primitive. Bit 0 always needs 268a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * to be unset) 269a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * [32:16] ParamOffset 270a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * 271a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */ 2729918fbd0268601b4dcd7c07c883733c959d78f9eMichel Dänzer /* XXX: This register number must be identical to the S_00B02C_USER_SGPR 2739918fbd0268601b4dcd7c07c883733c959d78f9eMichel Dänzer * register field value 2749918fbd0268601b4dcd7c07c883733c959d78f9eMichel Dänzer */ 275a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef params = use_sgpr(base->gallivm, SGPR_I32, 6); 276a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 277a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 278a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: Is this the input_index? */ 279a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef attr_number = lp_build_const_int32(gallivm, input_index); 280a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 281a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: Handle all possible interpolation modes */ 2821279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez switch (decl->Interp.Interpolate) { 283a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case TGSI_INTERPOLATE_COLOR: 28490c6eacdb4927e6395743d69e5efa0a3a0aec7ccMichel Dänzer /* XXX: Flat shading hangs the GPU */ 285d1e40b3d40b2e90ad4f275565f1ae27fe6f964ccMichel Dänzer if (si_shader_ctx->rctx->queued.named.rasterizer && 286d1e40b3d40b2e90ad4f275565f1ae27fe6f964ccMichel Dänzer si_shader_ctx->rctx->queued.named.rasterizer->flatshade) { 28790c6eacdb4927e6395743d69e5efa0a3a0aec7ccMichel Dänzer#if 0 288a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard intr_name = "llvm.SI.fs.interp.constant"; 28990c6eacdb4927e6395743d69e5efa0a3a0aec7ccMichel Dänzer#else 29090c6eacdb4927e6395743d69e5efa0a3a0aec7ccMichel Dänzer intr_name = "llvm.SI.fs.interp.linear.center"; 29190c6eacdb4927e6395743d69e5efa0a3a0aec7ccMichel Dänzer#endif 2921deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer } else { 2931deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer if (decl->Interp.Centroid) 2941deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer intr_name = "llvm.SI.fs.interp.persp.centroid"; 2951deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer else 2961deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer intr_name = "llvm.SI.fs.interp.persp.center"; 2971deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer } 298a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 299a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case TGSI_INTERPOLATE_CONSTANT: 30090c6eacdb4927e6395743d69e5efa0a3a0aec7ccMichel Dänzer /* XXX: Flat shading hangs the GPU */ 30190c6eacdb4927e6395743d69e5efa0a3a0aec7ccMichel Dänzer#if 0 302a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard intr_name = "llvm.SI.fs.interp.constant"; 303a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 30490c6eacdb4927e6395743d69e5efa0a3a0aec7ccMichel Dänzer#endif 305a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case TGSI_INTERPOLATE_LINEAR: 3061deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer if (decl->Interp.Centroid) 3071deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer intr_name = "llvm.SI.fs.interp.linear.centroid"; 3081deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer else 3091deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer intr_name = "llvm.SI.fs.interp.linear.center"; 3101deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer break; 3111deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer case TGSI_INTERPOLATE_PERSPECTIVE: 3121deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer if (decl->Interp.Centroid) 3131deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer intr_name = "llvm.SI.fs.interp.persp.centroid"; 3141deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer else 3151deb2be2b7887d7435e103fdb042857e745ff08dMichel Dänzer intr_name = "llvm.SI.fs.interp.persp.center"; 316a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 317a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 318a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard fprintf(stderr, "Warning: Unhandled interpolation mode.\n"); 319a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return; 320a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 321a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 322a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: Could there be more than TGSI_NUM_CHANNELS (4) ? */ 323a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { 324a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef args[3]; 325a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan); 326a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan); 327a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMTypeRef input_type = LLVMFloatTypeInContext(gallivm->context); 328a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard args[0] = llvm_chan; 329a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard args[1] = attr_number; 330a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard args[2] = params; 331a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard si_shader_ctx->radeon_bld.inputs[soa_index] = 332cf4ac69928eb17685958e6b3b01b97544560d90eTom Stellard build_intrinsic(base->gallivm->builder, intr_name, 333cf4ac69928eb17685958e6b3b01b97544560d90eTom Stellard input_type, args, 3, LLVMReadOnlyAttribute); 334a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 335a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 336a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 337a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void declare_input( 338a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct radeon_llvm_context * radeon_bld, 339a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned input_index, 340a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct tgsi_full_declaration *decl) 341a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 342a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct si_shader_context * si_shader_ctx = 343a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard si_shader_context(&radeon_bld->soa.bld_base); 344a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) { 345a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard declare_input_vs(si_shader_ctx, input_index, decl); 346a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else if (si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT) { 347a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard declare_input_fs(si_shader_ctx, input_index, decl); 348a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else { 349a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard fprintf(stderr, "Warning: Unsupported shader type,\n"); 350a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 351a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 352a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 353a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic LLVMValueRef fetch_constant( 354a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_tgsi_context * bld_base, 355a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const struct tgsi_full_src_register *reg, 356a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard enum tgsi_opcode_type type, 357a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned swizzle) 358a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 359a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_context * base = &bld_base->base; 360a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 361a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef const_ptr; 362a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef offset; 363022b54359a0c8cc0a219b19b1f381cce66b35d35Tom Stellard LLVMValueRef load; 364a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 365a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: Assume the pointer to the constant buffer is being stored in 3669918fbd0268601b4dcd7c07c883733c959d78f9eMichel Dänzer * SGPR[0:1] */ 367467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard const_ptr = use_sgpr(base->gallivm, SGPR_CONST_PTR_F32, 0); 368a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 369a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: This assumes that the constant buffer is not packed, so 370a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * CONST[0].x will have an offset of 0 and CONST[1].x will have an 371a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * offset of 4. */ 372a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard offset = lp_build_const_int32(base->gallivm, 373a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard (reg->Register.Index * 4) + swizzle); 374a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 375022b54359a0c8cc0a219b19b1f381cce66b35d35Tom Stellard load = build_indexed_load(base->gallivm, const_ptr, offset); 376022b54359a0c8cc0a219b19b1f381cce66b35d35Tom Stellard return bitcast(bld_base, type, load); 377a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 378a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 37926c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer/* Initialize arguments for the shader export intrinsic */ 38026c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzerstatic void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base, 38126c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer struct tgsi_full_declaration *d, 38226c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer unsigned index, 38326c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer unsigned target, 38426c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer LLVMValueRef *args) 38526c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer{ 38626c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer struct si_shader_context *si_shader_ctx = si_shader_context(bld_base); 38726c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer struct lp_build_context *uint = 38826c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer &si_shader_ctx->radeon_bld.soa.bld_base.uint_bld; 38926c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer struct lp_build_context *base = &bld_base->base; 39026c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer unsigned compressed = 0; 39126c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer unsigned chan; 39226c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer 393f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer if (si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT) { 394f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer int cbuf = target - V_008DFC_SQ_EXP_MRT; 395f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer 396f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer if (cbuf >= 0 && cbuf < 8) { 397f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer struct r600_context *rctx = si_shader_ctx->rctx; 398f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer compressed = (rctx->export_16bpc >> cbuf) & 0x1; 399f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer } 400f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer } 401f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer 402f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer if (compressed) { 403f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer /* Pixel shader needs to pack output values before export */ 404f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer for (chan = 0; chan < 2; chan++ ) { 405f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer LLVMValueRef *out_ptr = 406f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer si_shader_ctx->radeon_bld.soa.outputs[index]; 407f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer args[0] = LLVMBuildLoad(base->gallivm->builder, 408f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer out_ptr[2 * chan], ""); 409f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer args[1] = LLVMBuildLoad(base->gallivm->builder, 410f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer out_ptr[2 * chan + 1], ""); 411f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer args[chan + 5] = 412f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer build_intrinsic(base->gallivm->builder, 413f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer "llvm.SI.packf16", 414f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer LLVMInt32TypeInContext(base->gallivm->context), 415f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer args, 2, 416f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer LLVMReadNoneAttribute); 417f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer args[chan + 7] = args[chan + 5]; 418f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer } 419f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer 420f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer /* Set COMPR flag */ 421f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer args[4] = uint->one; 422f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer } else { 423f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer for (chan = 0; chan < 4; chan++ ) { 424f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer LLVMValueRef out_ptr = 425f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer si_shader_ctx->radeon_bld.soa.outputs[index][chan]; 426f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer /* +5 because the first output value will be 427f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer * the 6th argument to the intrinsic. */ 428f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer args[chan + 5] = LLVMBuildLoad(base->gallivm->builder, 429f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer out_ptr, ""); 430f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer } 431f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer 432f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer /* Clear COMPR flag */ 433f402acdbe244e5de9b2b616e0a908f5d1416ce89Michel Dänzer args[4] = uint->zero; 43426c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer } 43526c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer 43626c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer /* XXX: This controls which components of the output 43726c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer * registers actually get exported. (e.g bit 0 means export 43826c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer * X component, bit 1 means export Y component, etc.) I'm 43926c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer * hard coding this to 0xf for now. In the future, we might 44026c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer * want to do something else. */ 44126c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer args[0] = lp_build_const_int32(base->gallivm, 0xf); 44226c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer 44326c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer /* Specify whether the EXEC mask represents the valid mask */ 44426c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer args[1] = uint->zero; 44526c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer 44626c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer /* Specify whether this is the last export */ 44726c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer args[2] = uint->zero; 44826c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer 44926c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer /* Specify the target we are exporting */ 45026c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer args[3] = lp_build_const_int32(base->gallivm, target); 45126c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer 45226c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer /* XXX: We probably need to keep track of the output 45326c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer * values, so we know what we are passing to the next 45426c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer * stage. */ 45526c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer} 45626c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer 457a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* XXX: This is partially implemented for VS only at this point. It is not complete */ 458a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base) 459a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 460a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct si_shader_context * si_shader_ctx = si_shader_context(bld_base); 4613c09f11e5cefd437bb8185539430786dc245c96fChristian König struct si_shader * shader = &si_shader_ctx->shader->shader; 462a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_context * base = &bld_base->base; 463a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_context * uint = 464a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard &si_shader_ctx->radeon_bld.soa.bld_base.uint_bld; 465a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct tgsi_parse_context *parse = &si_shader_ctx->parse; 466a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef last_args[9] = { 0 }; 4673508815d178a5b2d22b2249a68974b0cf8f67069Christian König unsigned color_count = 0; 4683508815d178a5b2d22b2249a68974b0cf8f67069Christian König unsigned param_count = 0; 469a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 470a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard while (!tgsi_parse_end_of_tokens(parse)) { 471a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct tgsi_full_declaration *d = 472a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard &parse->FullToken.FullDeclaration; 473a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMValueRef args[9]; 474a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned target; 475a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned index; 476a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int i; 477a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 478a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard tgsi_parse_token(parse); 479a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (parse->FullToken.Token.Type != TGSI_TOKEN_TYPE_DECLARATION) 480a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard continue; 481a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 482a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard switch (d->Declaration.File) { 483a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case TGSI_FILE_INPUT: 484a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard i = shader->ninput++; 485a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard shader->input[i].name = d->Semantic.Name; 486a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard shader->input[i].sid = d->Semantic.Index; 4871279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez shader->input[i].interpolate = d->Interp.Interpolate; 4881279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez shader->input[i].centroid = d->Interp.Centroid; 4893508815d178a5b2d22b2249a68974b0cf8f67069Christian König continue; 4903508815d178a5b2d22b2249a68974b0cf8f67069Christian König 491a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case TGSI_FILE_OUTPUT: 492a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard i = shader->noutput++; 493a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard shader->output[i].name = d->Semantic.Name; 494a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard shader->output[i].sid = d->Semantic.Index; 4951279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez shader->output[i].interpolate = d->Interp.Interpolate; 496a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 497a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 4983508815d178a5b2d22b2249a68974b0cf8f67069Christian König default: 499a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard continue; 5003508815d178a5b2d22b2249a68974b0cf8f67069Christian König } 501a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 502a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard for (index = d->Range.First; index <= d->Range.Last; index++) { 503a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Select the correct target */ 504a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard switch(d->Semantic.Name) { 505a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case TGSI_SEMANTIC_POSITION: 506a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard target = V_008DFC_SQ_EXP_POS; 507a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 508a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case TGSI_SEMANTIC_COLOR: 509a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) { 510a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard target = V_008DFC_SQ_EXP_PARAM + param_count; 511dd9d6194599e08cc23d3a7cc354cfd0366d2caaeMichel Dänzer shader->output[i].param_offset = param_count; 512a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard param_count++; 513a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else { 514a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard target = V_008DFC_SQ_EXP_MRT + color_count; 515a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard color_count++; 516a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 517a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 518a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case TGSI_SEMANTIC_GENERIC: 519a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard target = V_008DFC_SQ_EXP_PARAM + param_count; 520dd9d6194599e08cc23d3a7cc354cfd0366d2caaeMichel Dänzer shader->output[i].param_offset = param_count; 521a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard param_count++; 522a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 523a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard default: 524a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard target = 0; 525a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard fprintf(stderr, 526a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard "Warning: SI unhandled output type:%d\n", 527a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard d->Semantic.Name); 528a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 529a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 53026c7139d2c594edbe33cbbd5f786988a529389c8Michel Dänzer si_llvm_init_export_args(bld_base, d, index, target, args); 531a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 532a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX ? 533a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard (d->Semantic.Name == TGSI_SEMANTIC_POSITION) : 534a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard (d->Semantic.Name == TGSI_SEMANTIC_COLOR)) { 535a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (last_args[0]) { 536a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard lp_build_intrinsic(base->gallivm->builder, 537a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard "llvm.SI.export", 538a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMVoidTypeInContext(base->gallivm->context), 539a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard last_args, 9); 540a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 541a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 542a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard memcpy(last_args, args, sizeof(args)); 543a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } else { 544a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard lp_build_intrinsic(base->gallivm->builder, 545a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard "llvm.SI.export", 546a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMVoidTypeInContext(base->gallivm->context), 547a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard args, 9); 548a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 549a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 550a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 551a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 552a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 553f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König if (!last_args[0]) { 554f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König assert(si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT); 555f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König 556f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König /* Specify which components to enable */ 557f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König last_args[0] = lp_build_const_int32(base->gallivm, 0x0); 558f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König 559f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König /* Specify the target we are exporting */ 560f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König last_args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRT); 561f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König 562f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König /* Set COMPR flag to zero to export data as 32-bit */ 563f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König last_args[4] = uint->zero; 564f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König 565f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König /* dummy bits */ 566f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König last_args[5]= uint->zero; 567f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König last_args[6]= uint->zero; 568f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König last_args[7]= uint->zero; 569f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König last_args[8]= uint->zero; 570f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König } 571f18fd255cf283cdf4ba9326d437d1543fd38a139Christian König 572a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Specify whether the EXEC mask represents the valid mask */ 573a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard last_args[1] = lp_build_const_int32(base->gallivm, 574a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT); 575a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 576a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Specify that this is the last export */ 577a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard last_args[2] = lp_build_const_int32(base->gallivm, 1); 578a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 579a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard lp_build_intrinsic(base->gallivm->builder, 580a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard "llvm.SI.export", 581a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMVoidTypeInContext(base->gallivm->context), 582a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard last_args, 9); 583a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 584a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* XXX: Look up what this function does */ 585a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]);*/ 586a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 587a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 588a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void tex_fetch_args( 589a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_tgsi_context * bld_base, 590a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_emit_data * emit_data) 591a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 592c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer const struct tgsi_full_instruction * inst = emit_data->inst; 593467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard LLVMValueRef ptr; 594467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard LLVMValueRef offset; 595467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard 596a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* WriteMask */ 597250b7fdd2610bf03292399c7d489c82de22fc682Christian König /* XXX: should be optimized using emit_data->inst->Dst[0].Register.WriteMask*/ 598250b7fdd2610bf03292399c7d489c82de22fc682Christian König emit_data->args[0] = lp_build_const_int32(bld_base->base.gallivm, 0xf); 599a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 600a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Coordinates */ 601a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: Not all sample instructions need 4 address arguments. */ 602c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) { 603c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer LLVMValueRef src_w; 604c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer unsigned chan; 605c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer LLVMValueRef coords[4]; 606c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer 607c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4); 608c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer src_w = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_W); 609c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer 610c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer for (chan = 0; chan < 3; chan++ ) { 611c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer LLVMValueRef arg = lp_build_emit_fetch(bld_base, 612c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer emit_data->inst, 0, chan); 613c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer coords[chan] = lp_build_emit_llvm_binary(bld_base, 614c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer TGSI_OPCODE_DIV, 615c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer arg, src_w); 616c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer } 617c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer coords[3] = bld_base->base.one; 618c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer emit_data->args[1] = lp_build_gather_values(bld_base->base.gallivm, 619c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer coords, 4); 620c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer } else 621c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer emit_data->args[1] = lp_build_emit_fetch(bld_base, emit_data->inst, 622c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer 0, LP_CHAN_ALL); 623a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 624a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Resource */ 62589ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard ptr = use_sgpr(bld_base->base.gallivm, SGPR_CONST_PTR_V8I32, 4); 626467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard offset = lp_build_const_int32(bld_base->base.gallivm, 62792b96a883f5ed53d88ec148c8212c5a8348e97abChristian König emit_data->inst->Src[1].Register.Index); 628467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard emit_data->args[2] = build_indexed_load(bld_base->base.gallivm, 629467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard ptr, offset); 630a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 631a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Sampler */ 63289ece086bcd2186ab53cb6a69d53005893cab0eaTom Stellard ptr = use_sgpr(bld_base->base.gallivm, SGPR_CONST_PTR_V4I32, 2); 633467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard offset = lp_build_const_int32(bld_base->base.gallivm, 63492b96a883f5ed53d88ec148c8212c5a8348e97abChristian König emit_data->inst->Src[1].Register.Index); 635467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard emit_data->args[3] = build_indexed_load(bld_base->base.gallivm, 636467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard ptr, offset); 637a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 638a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Dimensions */ 639a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: We might want to pass this information to the shader at some. */ 640a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* emit_data->args[4] = lp_build_const_int32(bld_base->base.gallivm, 641a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard emit_data->inst->Texture.Texture); 642a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard*/ 643a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 644467f51613eb1f2cdaa8624bbbb3d5fae2abca4f2Tom Stellard emit_data->arg_count = 4; 645a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* XXX: To optimize, we could use a float or v2f32, if the last bits of 646a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * the writemask are clear */ 647a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard emit_data->dst_type = LLVMVectorType( 648a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMFloatTypeInContext(bld_base->base.gallivm->context), 649a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 4); 650a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 651a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 652a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic const struct lp_build_tgsi_action tex_action = { 653a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard .fetch_args = tex_fetch_args, 654a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard .emit = lp_build_tgsi_intrinsic, 655a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard .intr_name = "llvm.SI.sample" 656a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}; 657a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 658a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 659a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardint si_pipe_shader_create( 660a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct pipe_context *ctx, 661a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct si_pipe_shader *shader) 662a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 663a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct r600_context *rctx = (struct r600_context*)ctx; 664d1e40b3d40b2e90ad4f275565f1ae27fe6f964ccMichel Dänzer struct si_pipe_shader_selector *sel = shader->selector; 665a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct si_shader_context si_shader_ctx; 666a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct tgsi_shader_info shader_info; 667a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct lp_build_tgsi_context * bld_base; 668a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMModuleRef mod; 669a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned char * inst_bytes; 670a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned inst_byte_count; 671a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned i; 672d51b9b70d581fe47370897ec517f229f1cea2903Christian König uint32_t *ptr; 6734c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer bool dump; 6744c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer 6754c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer dump = debug_get_bool_option("RADEON_DUMP_SHADERS", FALSE); 676a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 677a5ac8ee2c5e7dad3985b06c620d96cf077804ff9Tom Stellard memset(&si_shader_ctx.radeon_bld, 0, sizeof(si_shader_ctx.radeon_bld)); 678a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard radeon_llvm_context_init(&si_shader_ctx.radeon_bld); 679a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bld_base = &si_shader_ctx.radeon_bld.soa.bld_base; 680a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 681d1e40b3d40b2e90ad4f275565f1ae27fe6f964ccMichel Dänzer tgsi_scan_shader(sel->tokens, &shader_info); 682a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bld_base->info = &shader_info; 683a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = fetch_constant; 684a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bld_base->emit_epilogue = si_llvm_emit_epilogue; 685a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 686a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bld_base->op_actions[TGSI_OPCODE_TEX] = tex_action; 687c2bae6b91de8bd023dbac7fef4c2a3b8eba28afaMichel Dänzer bld_base->op_actions[TGSI_OPCODE_TXP] = tex_action; 688a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 689a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard si_shader_ctx.radeon_bld.load_input = declare_input; 690d1e40b3d40b2e90ad4f275565f1ae27fe6f964ccMichel Dänzer si_shader_ctx.tokens = sel->tokens; 691a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard tgsi_parse_init(&si_shader_ctx.parse, si_shader_ctx.tokens); 692a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard si_shader_ctx.shader = shader; 693a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard si_shader_ctx.type = si_shader_ctx.parse.FullHeader.Processor.Processor; 694a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard si_shader_ctx.rctx = rctx; 695a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 696835098a5290e59bb7b468eb987db67b0e1913c67Christian König shader->shader.nr_cbufs = rctx->framebuffer.nr_cbufs; 697a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 698185fc9a5efc85d8eadf14d38399e43efea3388d0Tom Stellard /* Dump TGSI code before doing TGSI->LLVM conversion in case the 699185fc9a5efc85d8eadf14d38399e43efea3388d0Tom Stellard * conversion fails. */ 700185fc9a5efc85d8eadf14d38399e43efea3388d0Tom Stellard if (dump) { 701d1e40b3d40b2e90ad4f275565f1ae27fe6f964ccMichel Dänzer tgsi_dump(sel->tokens, 0); 702185fc9a5efc85d8eadf14d38399e43efea3388d0Tom Stellard } 703185fc9a5efc85d8eadf14d38399e43efea3388d0Tom Stellard 704d1e40b3d40b2e90ad4f275565f1ae27fe6f964ccMichel Dänzer if (!lp_build_tgsi_llvm(bld_base, sel->tokens)) { 70582cd9c0fc2838a153006a646b0d356ed54b8680eMichel Dänzer fprintf(stderr, "Failed to translate shader from TGSI to LLVM\n"); 70682cd9c0fc2838a153006a646b0d356ed54b8680eMichel Dänzer return -EINVAL; 70782cd9c0fc2838a153006a646b0d356ed54b8680eMichel Dänzer } 708a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 709a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard radeon_llvm_finalize_module(&si_shader_ctx.radeon_bld); 710a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 711a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard mod = bld_base->base.gallivm->module; 7124c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer if (dump) { 7134c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer LLVMDumpModule(mod); 7144c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer } 7154c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer radeon_llvm_compile(mod, &inst_bytes, &inst_byte_count, "SI", dump); 7164c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer if (dump) { 7174c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer fprintf(stderr, "SI CODE:\n"); 7184c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer for (i = 0; i < inst_byte_count; i+=4 ) { 7194c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer fprintf(stderr, "%02x%02x%02x%02x\n", inst_bytes[i + 3], 7204c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer inst_bytes[i + 2], inst_bytes[i + 1], 7214c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer inst_bytes[i]); 7224c4ef9c29acf4f1f40aa3c5d268322efd26c1786Michel Dänzer } 723a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 724a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 725a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard shader->num_sgprs = util_le32_to_cpu(*(uint32_t*)inst_bytes); 726a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard shader->num_vgprs = util_le32_to_cpu(*(uint32_t*)(inst_bytes + 4)); 727a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard shader->spi_ps_input_ena = util_le32_to_cpu(*(uint32_t*)(inst_bytes + 8)); 728a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 7294b64fa2ff18ecf5b991f3f5e11daf1e3d8314664Michel Dänzer radeon_llvm_dispose(&si_shader_ctx.radeon_bld); 730a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard tgsi_parse_free(&si_shader_ctx.parse); 731a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 732a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* copy new shader */ 733d51b9b70d581fe47370897ec517f229f1cea2903Christian König si_resource_reference(&shader->bo, NULL); 734d51b9b70d581fe47370897ec517f229f1cea2903Christian König shader->bo = si_resource_create_custom(ctx->screen, PIPE_USAGE_IMMUTABLE, 735d51b9b70d581fe47370897ec517f229f1cea2903Christian König inst_byte_count - 12); 736a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (shader->bo == NULL) { 737d51b9b70d581fe47370897ec517f229f1cea2903Christian König return -ENOMEM; 738d51b9b70d581fe47370897ec517f229f1cea2903Christian König } 739a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 740d51b9b70d581fe47370897ec517f229f1cea2903Christian König ptr = (uint32_t*)rctx->ws->buffer_map(shader->bo->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); 741d51b9b70d581fe47370897ec517f229f1cea2903Christian König if (0 /*R600_BIG_ENDIAN*/) { 742d51b9b70d581fe47370897ec517f229f1cea2903Christian König for (i = 0; i < (inst_byte_count-12)/4; ++i) { 743d51b9b70d581fe47370897ec517f229f1cea2903Christian König ptr[i] = util_bswap32(*(uint32_t*)(inst_bytes+12 + i*4)); 744a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 745d51b9b70d581fe47370897ec517f229f1cea2903Christian König } else { 746d51b9b70d581fe47370897ec517f229f1cea2903Christian König memcpy(ptr, inst_bytes + 12, inst_byte_count - 12); 747a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 748d51b9b70d581fe47370897ec517f229f1cea2903Christian König rctx->ws->buffer_unmap(shader->bo->cs_buf); 749a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 750a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard free(inst_bytes); 751a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 752a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return 0; 753a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 754a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 755a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid si_pipe_shader_destroy(struct pipe_context *ctx, struct si_pipe_shader *shader) 756a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 757fe41287ffa8cb35421cadfb16d4cc27c5fcb8b76Christian König si_resource_reference(&shader->bo, NULL); 758a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 759