swr_shader.cpp revision b19d214b238228bfebfe3869b6aee540993fe706
1/**************************************************************************** 2 * Copyright (C) 2015 Intel Corporation. All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 ***************************************************************************/ 23 24#include "JitManager.h" 25#include "state.h" 26#include "state_llvm.h" 27#include "builder.h" 28 29#include "llvm-c/Core.h" 30#include "llvm/Support/CBindingWrapping.h" 31 32#include "tgsi/tgsi_strings.h" 33#include "gallivm/lp_bld_init.h" 34#include "gallivm/lp_bld_flow.h" 35#include "gallivm/lp_bld_struct.h" 36#include "gallivm/lp_bld_tgsi.h" 37 38#include "swr_context.h" 39#include "swr_context_llvm.h" 40#include "swr_state.h" 41#include "swr_screen.h" 42 43bool operator==(const swr_jit_fs_key &lhs, const swr_jit_fs_key &rhs) 44{ 45 return !memcmp(&lhs, &rhs, sizeof(lhs)); 46} 47 48bool operator==(const swr_jit_vs_key &lhs, const swr_jit_vs_key &rhs) 49{ 50 return !memcmp(&lhs, &rhs, sizeof(lhs)); 51} 52 53static void 54swr_generate_sampler_key(const struct lp_tgsi_info &info, 55 struct swr_context *ctx, 56 unsigned shader_type, 57 struct swr_jit_sampler_key &key) 58{ 59 key.nr_samplers = info.base.file_max[TGSI_FILE_SAMPLER] + 1; 60 61 for (unsigned i = 0; i < key.nr_samplers; i++) { 62 if (info.base.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) { 63 lp_sampler_static_sampler_state( 64 &key.sampler[i].sampler_state, 65 ctx->samplers[shader_type][i]); 66 } 67 } 68 69 /* 70 * XXX If TGSI_FILE_SAMPLER_VIEW exists assume all texture opcodes 71 * are dx10-style? Can't really have mixed opcodes, at least not 72 * if we want to skip the holes here (without rescanning tgsi). 73 */ 74 if (info.base.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) { 75 key.nr_sampler_views = 76 info.base.file_max[TGSI_FILE_SAMPLER_VIEW] + 1; 77 for (unsigned i = 0; i < key.nr_sampler_views; i++) { 78 if (info.base.file_mask[TGSI_FILE_SAMPLER_VIEW] & (1 << i)) { 79 lp_sampler_static_texture_state( 80 &key.sampler[i].texture_state, 81 ctx->sampler_views[shader_type][i]); 82 } 83 } 84 } else { 85 key.nr_sampler_views = key.nr_samplers; 86 for (unsigned i = 0; i < key.nr_sampler_views; i++) { 87 if (info.base.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) { 88 lp_sampler_static_texture_state( 89 &key.sampler[i].texture_state, 90 ctx->sampler_views[shader_type][i]); 91 } 92 } 93 } 94} 95 96void 97swr_generate_fs_key(struct swr_jit_fs_key &key, 98 struct swr_context *ctx, 99 swr_fragment_shader *swr_fs) 100{ 101 memset(&key, 0, sizeof(key)); 102 103 key.nr_cbufs = ctx->framebuffer.nr_cbufs; 104 key.light_twoside = ctx->rasterizer->light_twoside; 105 memcpy(&key.vs_output_semantic_name, 106 &ctx->vs->info.base.output_semantic_name, 107 sizeof(key.vs_output_semantic_name)); 108 memcpy(&key.vs_output_semantic_idx, 109 &ctx->vs->info.base.output_semantic_index, 110 sizeof(key.vs_output_semantic_idx)); 111 112 swr_generate_sampler_key(swr_fs->info, ctx, PIPE_SHADER_FRAGMENT, key); 113} 114 115void 116swr_generate_vs_key(struct swr_jit_vs_key &key, 117 struct swr_context *ctx, 118 swr_vertex_shader *swr_vs) 119{ 120 memset(&key, 0, sizeof(key)); 121 122 swr_generate_sampler_key(swr_vs->info, ctx, PIPE_SHADER_VERTEX, key); 123} 124 125struct BuilderSWR : public Builder { 126 BuilderSWR(JitManager *pJitMgr) 127 : Builder(pJitMgr) 128 { 129 pJitMgr->SetupNewModule(); 130 } 131 132 PFN_VERTEX_FUNC CompileVS(struct swr_context *ctx, swr_jit_vs_key &key); 133 PFN_PIXEL_KERNEL CompileFS(struct swr_context *ctx, swr_jit_fs_key &key); 134}; 135 136PFN_VERTEX_FUNC 137BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key) 138{ 139 struct swr_vertex_shader *swr_vs = ctx->vs; 140 141 swr_vs->linkageMask = 0; 142 143 for (unsigned i = 0; i < swr_vs->info.base.num_outputs; i++) { 144 switch (swr_vs->info.base.output_semantic_name[i]) { 145 case TGSI_SEMANTIC_POSITION: 146 break; 147 default: 148 swr_vs->linkageMask |= (1 << i); 149 break; 150 } 151 } 152 153 // tgsi_dump(swr_vs->pipe.tokens, 0); 154 155 struct gallivm_state *gallivm = 156 gallivm_create("VS", wrap(&JM()->mContext)); 157 gallivm->module = wrap(JM()->mpCurrentModule); 158 159 LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS]; 160 LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS]; 161 162 memset(outputs, 0, sizeof(outputs)); 163 164 AttrBuilder attrBuilder; 165 attrBuilder.addStackAlignmentAttr(JM()->mVWidth * sizeof(float)); 166 AttributeSet attrSet = AttributeSet::get( 167 JM()->mContext, AttributeSet::FunctionIndex, attrBuilder); 168 169 std::vector<Type *> vsArgs{PointerType::get(Gen_swr_draw_context(JM()), 0), 170 PointerType::get(Gen_SWR_VS_CONTEXT(JM()), 0)}; 171 FunctionType *vsFuncType = 172 FunctionType::get(Type::getVoidTy(JM()->mContext), vsArgs, false); 173 174 // create new vertex shader function 175 auto pFunction = Function::Create(vsFuncType, 176 GlobalValue::ExternalLinkage, 177 "VS", 178 JM()->mpCurrentModule); 179 pFunction->addAttributes(AttributeSet::FunctionIndex, attrSet); 180 181 BasicBlock *block = BasicBlock::Create(JM()->mContext, "entry", pFunction); 182 IRB()->SetInsertPoint(block); 183 LLVMPositionBuilderAtEnd(gallivm->builder, wrap(block)); 184 185 auto argitr = pFunction->arg_begin(); 186 Value *hPrivateData = &*argitr++; 187 hPrivateData->setName("hPrivateData"); 188 Value *pVsCtx = &*argitr++; 189 pVsCtx->setName("vsCtx"); 190 191 Value *consts_ptr = GEP(hPrivateData, {C(0), C(swr_draw_context_constantVS)}); 192 193 consts_ptr->setName("vs_constants"); 194 Value *const_sizes_ptr = 195 GEP(hPrivateData, {0, swr_draw_context_num_constantsVS}); 196 const_sizes_ptr->setName("num_vs_constants"); 197 198 Value *vtxInput = LOAD(pVsCtx, {0, SWR_VS_CONTEXT_pVin}); 199 200 for (uint32_t attrib = 0; attrib < PIPE_MAX_SHADER_INPUTS; attrib++) { 201 const unsigned mask = swr_vs->info.base.input_usage_mask[attrib]; 202 for (uint32_t channel = 0; channel < TGSI_NUM_CHANNELS; channel++) { 203 if (mask & (1 << channel)) { 204 inputs[attrib][channel] = 205 wrap(LOAD(vtxInput, {0, 0, attrib, channel})); 206 } 207 } 208 } 209 210 struct lp_build_sampler_soa *sampler = 211 swr_sampler_soa_create(key.sampler, PIPE_SHADER_VERTEX); 212 213 struct lp_bld_tgsi_system_values system_values; 214 memset(&system_values, 0, sizeof(system_values)); 215 system_values.instance_id = wrap(LOAD(pVsCtx, {0, SWR_VS_CONTEXT_InstanceID})); 216 system_values.vertex_id = wrap(LOAD(pVsCtx, {0, SWR_VS_CONTEXT_VertexID})); 217 218 lp_build_tgsi_soa(gallivm, 219 swr_vs->pipe.tokens, 220 lp_type_float_vec(32, 32 * 8), 221 NULL, // mask 222 wrap(consts_ptr), 223 wrap(const_sizes_ptr), 224 &system_values, 225 inputs, 226 outputs, 227 wrap(hPrivateData), // (sampler context) 228 NULL, // thread data 229 sampler, // sampler 230 &swr_vs->info.base, 231 NULL); // geometry shader face 232 233 IRB()->SetInsertPoint(unwrap(LLVMGetInsertBlock(gallivm->builder))); 234 235 Value *vtxOutput = LOAD(pVsCtx, {0, SWR_VS_CONTEXT_pVout}); 236 237 for (uint32_t channel = 0; channel < TGSI_NUM_CHANNELS; channel++) { 238 for (uint32_t attrib = 0; attrib < PIPE_MAX_SHADER_OUTPUTS; attrib++) { 239 if (!outputs[attrib][channel]) 240 continue; 241 242 Value *val = LOAD(unwrap(outputs[attrib][channel])); 243 244 uint32_t outSlot = attrib; 245 if (swr_vs->info.base.output_semantic_name[attrib] == TGSI_SEMANTIC_PSIZE) 246 outSlot = VERTEX_POINT_SIZE_SLOT; 247 STORE(val, vtxOutput, {0, 0, outSlot, channel}); 248 } 249 } 250 251 RET_VOID(); 252 253 gallivm_verify_function(gallivm, wrap(pFunction)); 254 gallivm_compile_module(gallivm); 255 256 // lp_debug_dump_value(func); 257 258 PFN_VERTEX_FUNC pFunc = 259 (PFN_VERTEX_FUNC)gallivm_jit_function(gallivm, wrap(pFunction)); 260 261 debug_printf("vert shader %p\n", pFunc); 262 assert(pFunc && "Error: VertShader = NULL"); 263 264#if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR >= 5) 265 JM()->mIsModuleFinalized = true; 266#endif 267 268 return pFunc; 269} 270 271PFN_VERTEX_FUNC 272swr_compile_vs(struct swr_context *ctx, swr_jit_vs_key &key) 273{ 274 BuilderSWR builder( 275 reinterpret_cast<JitManager *>(swr_screen(ctx->pipe.screen)->hJitMgr)); 276 return builder.CompileVS(ctx, key); 277} 278 279static unsigned 280locate_linkage(ubyte name, ubyte index, struct tgsi_shader_info *info) 281{ 282 for (int i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) { 283 if ((info->output_semantic_name[i] == name) 284 && (info->output_semantic_index[i] == index)) { 285 return i - 1; // position is not part of the linkage 286 } 287 } 288 289 if (name == TGSI_SEMANTIC_COLOR) { // BCOLOR fallback 290 for (int i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) { 291 if ((info->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) 292 && (info->output_semantic_index[i] == index)) { 293 return i - 1; // position is not part of the linkage 294 } 295 } 296 } 297 298 return 0xFFFFFFFF; 299} 300 301PFN_PIXEL_KERNEL 302BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key) 303{ 304 struct swr_fragment_shader *swr_fs = ctx->fs; 305 306 // tgsi_dump(swr_fs->pipe.tokens, 0); 307 308 struct gallivm_state *gallivm = 309 gallivm_create("FS", wrap(&JM()->mContext)); 310 gallivm->module = wrap(JM()->mpCurrentModule); 311 312 LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS]; 313 LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS]; 314 315 memset(inputs, 0, sizeof(inputs)); 316 memset(outputs, 0, sizeof(outputs)); 317 318 struct lp_build_sampler_soa *sampler = NULL; 319 320 AttrBuilder attrBuilder; 321 attrBuilder.addStackAlignmentAttr(JM()->mVWidth * sizeof(float)); 322 AttributeSet attrSet = AttributeSet::get( 323 JM()->mContext, AttributeSet::FunctionIndex, attrBuilder); 324 325 std::vector<Type *> fsArgs{PointerType::get(Gen_swr_draw_context(JM()), 0), 326 PointerType::get(Gen_SWR_PS_CONTEXT(JM()), 0)}; 327 FunctionType *funcType = 328 FunctionType::get(Type::getVoidTy(JM()->mContext), fsArgs, false); 329 330 auto pFunction = Function::Create(funcType, 331 GlobalValue::ExternalLinkage, 332 "FS", 333 JM()->mpCurrentModule); 334 pFunction->addAttributes(AttributeSet::FunctionIndex, attrSet); 335 336 BasicBlock *block = BasicBlock::Create(JM()->mContext, "entry", pFunction); 337 IRB()->SetInsertPoint(block); 338 LLVMPositionBuilderAtEnd(gallivm->builder, wrap(block)); 339 340 auto args = pFunction->arg_begin(); 341 Value *hPrivateData = &*args++; 342 hPrivateData->setName("hPrivateData"); 343 Value *pPS = &*args++; 344 pPS->setName("psCtx"); 345 346 Value *consts_ptr = GEP(hPrivateData, {0, swr_draw_context_constantFS}); 347 consts_ptr->setName("fs_constants"); 348 Value *const_sizes_ptr = 349 GEP(hPrivateData, {0, swr_draw_context_num_constantsFS}); 350 const_sizes_ptr->setName("num_fs_constants"); 351 352 // xxx should check for flat shading versus interpolation 353 354 355 // load *pAttribs, *pPerspAttribs 356 Value *pRawAttribs = LOAD(pPS, {0, SWR_PS_CONTEXT_pAttribs}, "pRawAttribs"); 357 Value *pPerspAttribs = 358 LOAD(pPS, {0, SWR_PS_CONTEXT_pPerspAttribs}, "pPerspAttribs"); 359 360 swr_fs->constantMask = 0; 361 swr_fs->pointSpriteMask = 0; 362 363 for (int attrib = 0; attrib < PIPE_MAX_SHADER_INPUTS; attrib++) { 364 const unsigned mask = swr_fs->info.base.input_usage_mask[attrib]; 365 const unsigned interpMode = swr_fs->info.base.input_interpolate[attrib]; 366 const unsigned interpLoc = swr_fs->info.base.input_interpolate_loc[attrib]; 367 368 if (!mask) 369 continue; 370 371 // load i,j 372 Value *vi = nullptr, *vj = nullptr; 373 switch (interpLoc) { 374 case TGSI_INTERPOLATE_LOC_CENTER: 375 vi = LOAD(pPS, {0, SWR_PS_CONTEXT_vI, PixelPositions_center}, "i"); 376 vj = LOAD(pPS, {0, SWR_PS_CONTEXT_vJ, PixelPositions_center}, "j"); 377 break; 378 case TGSI_INTERPOLATE_LOC_CENTROID: 379 vi = LOAD(pPS, {0, SWR_PS_CONTEXT_vI, PixelPositions_centroid}, "i"); 380 vj = LOAD(pPS, {0, SWR_PS_CONTEXT_vJ, PixelPositions_centroid}, "j"); 381 break; 382 case TGSI_INTERPOLATE_LOC_SAMPLE: 383 vi = LOAD(pPS, {0, SWR_PS_CONTEXT_vI, PixelPositions_sample}, "i"); 384 vj = LOAD(pPS, {0, SWR_PS_CONTEXT_vJ, PixelPositions_sample}, "j"); 385 break; 386 } 387 388 // load/compute w 389 Value *vw = nullptr, *pAttribs; 390 if (interpMode == TGSI_INTERPOLATE_PERSPECTIVE) { 391 pAttribs = pPerspAttribs; 392 switch (interpLoc) { 393 case TGSI_INTERPOLATE_LOC_CENTER: 394 vw = VRCP(LOAD(pPS, {0, SWR_PS_CONTEXT_vOneOverW, PixelPositions_center})); 395 break; 396 case TGSI_INTERPOLATE_LOC_CENTROID: 397 vw = VRCP(LOAD(pPS, {0, SWR_PS_CONTEXT_vOneOverW, PixelPositions_centroid})); 398 break; 399 case TGSI_INTERPOLATE_LOC_SAMPLE: 400 vw = VRCP(LOAD(pPS, {0, SWR_PS_CONTEXT_vOneOverW, PixelPositions_sample})); 401 break; 402 } 403 } else { 404 pAttribs = pRawAttribs; 405 vw = VIMMED1(1.f); 406 } 407 408 vw->setName("w"); 409 410 ubyte semantic_name = swr_fs->info.base.input_semantic_name[attrib]; 411 ubyte semantic_idx = swr_fs->info.base.input_semantic_index[attrib]; 412 413 if (semantic_name == TGSI_SEMANTIC_FACE) { 414 Value *ff = 415 UI_TO_FP(LOAD(pPS, {0, SWR_PS_CONTEXT_frontFace}), mFP32Ty); 416 ff = FSUB(FMUL(ff, C(2.0f)), C(1.0f)); 417 ff = VECTOR_SPLAT(JM()->mVWidth, ff, "vFrontFace"); 418 419 inputs[attrib][0] = wrap(ff); 420 inputs[attrib][1] = wrap(VIMMED1(0.0f)); 421 inputs[attrib][2] = wrap(VIMMED1(0.0f)); 422 inputs[attrib][3] = wrap(VIMMED1(1.0f)); 423 continue; 424 } else if (semantic_name == TGSI_SEMANTIC_POSITION) { // gl_FragCoord 425 inputs[attrib][0] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vX, PixelPositions_center}, "vX")); 426 inputs[attrib][1] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vY, PixelPositions_center}, "vY")); 427 inputs[attrib][2] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vZ}, "vZ")); 428 inputs[attrib][3] = 429 wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vOneOverW, PixelPositions_center}, "vOneOverW")); 430 continue; 431 } else if (semantic_name == TGSI_SEMANTIC_PRIMID) { 432 Value *primID = LOAD(pPS, {0, SWR_PS_CONTEXT_primID}, "primID"); 433 inputs[attrib][0] = wrap(VECTOR_SPLAT(JM()->mVWidth, primID)); 434 inputs[attrib][1] = wrap(VIMMED1(0)); 435 inputs[attrib][2] = wrap(VIMMED1(0)); 436 inputs[attrib][3] = wrap(VIMMED1(0)); 437 continue; 438 } 439 440 unsigned linkedAttrib = 441 locate_linkage(semantic_name, semantic_idx, &ctx->vs->info.base); 442 if (linkedAttrib == 0xFFFFFFFF) { 443 // not found - check for point sprite 444 if (ctx->rasterizer->sprite_coord_enable) { 445 linkedAttrib = ctx->vs->info.base.num_outputs - 1; 446 swr_fs->pointSpriteMask |= (1 << linkedAttrib); 447 } else { 448 fprintf(stderr, 449 "Missing %s[%d]\n", 450 tgsi_semantic_names[semantic_name], 451 semantic_idx); 452 assert(0 && "attribute linkage not found"); 453 } 454 } 455 456 if (interpMode == TGSI_INTERPOLATE_CONSTANT) { 457 swr_fs->constantMask |= 1 << linkedAttrib; 458 } 459 460 for (int channel = 0; channel < TGSI_NUM_CHANNELS; channel++) { 461 if (mask & (1 << channel)) { 462 Value *indexA = C(linkedAttrib * 12 + channel); 463 Value *indexB = C(linkedAttrib * 12 + channel + 4); 464 Value *indexC = C(linkedAttrib * 12 + channel + 8); 465 466 if ((semantic_name == TGSI_SEMANTIC_COLOR) 467 && ctx->rasterizer->light_twoside) { 468 unsigned bcolorAttrib = locate_linkage( 469 TGSI_SEMANTIC_BCOLOR, semantic_idx, &ctx->vs->info.base); 470 471 unsigned diff = 12 * (bcolorAttrib - linkedAttrib); 472 473 Value *back = 474 XOR(C(1), LOAD(pPS, {0, SWR_PS_CONTEXT_frontFace}), "backFace"); 475 476 Value *offset = MUL(back, C(diff)); 477 offset->setName("offset"); 478 479 indexA = ADD(indexA, offset); 480 indexB = ADD(indexB, offset); 481 indexC = ADD(indexC, offset); 482 483 if (interpMode == TGSI_INTERPOLATE_CONSTANT) { 484 swr_fs->constantMask |= 1 << bcolorAttrib; 485 } 486 } 487 488 Value *va = VBROADCAST(LOAD(GEP(pAttribs, indexA))); 489 Value *vb = VBROADCAST(LOAD(GEP(pAttribs, indexB))); 490 Value *vc = VBROADCAST(LOAD(GEP(pAttribs, indexC))); 491 492 if (interpMode == TGSI_INTERPOLATE_CONSTANT) { 493 inputs[attrib][channel] = wrap(va); 494 } else { 495 Value *vk = FSUB(FSUB(VIMMED1(1.0f), vi), vj); 496 497 vc = FMUL(vk, vc); 498 499 Value *interp = FMUL(va, vi); 500 Value *interp1 = FMUL(vb, vj); 501 interp = FADD(interp, interp1); 502 interp = FADD(interp, vc); 503 if (interpMode == TGSI_INTERPOLATE_PERSPECTIVE) 504 interp = FMUL(interp, vw); 505 inputs[attrib][channel] = wrap(interp); 506 } 507 } 508 } 509 } 510 511 sampler = swr_sampler_soa_create(key.sampler, PIPE_SHADER_FRAGMENT); 512 513 struct lp_bld_tgsi_system_values system_values; 514 memset(&system_values, 0, sizeof(system_values)); 515 516 struct lp_build_mask_context mask; 517 518 if (swr_fs->info.base.uses_kill) { 519 Value *mask_val = LOAD(pPS, {0, SWR_PS_CONTEXT_activeMask}, "activeMask"); 520 lp_build_mask_begin( 521 &mask, gallivm, lp_type_float_vec(32, 32 * 8), wrap(mask_val)); 522 } 523 524 lp_build_tgsi_soa(gallivm, 525 swr_fs->pipe.tokens, 526 lp_type_float_vec(32, 32 * 8), 527 swr_fs->info.base.uses_kill ? &mask : NULL, // mask 528 wrap(consts_ptr), 529 wrap(const_sizes_ptr), 530 &system_values, 531 inputs, 532 outputs, 533 wrap(hPrivateData), 534 NULL, // thread data 535 sampler, // sampler 536 &swr_fs->info.base, 537 NULL); // geometry shader face 538 539 IRB()->SetInsertPoint(unwrap(LLVMGetInsertBlock(gallivm->builder))); 540 541 for (uint32_t attrib = 0; attrib < swr_fs->info.base.num_outputs; 542 attrib++) { 543 switch (swr_fs->info.base.output_semantic_name[attrib]) { 544 case TGSI_SEMANTIC_POSITION: { 545 // write z 546 LLVMValueRef outZ = 547 LLVMBuildLoad(gallivm->builder, outputs[attrib][2], ""); 548 STORE(unwrap(outZ), pPS, {0, SWR_PS_CONTEXT_vZ}); 549 break; 550 } 551 case TGSI_SEMANTIC_COLOR: { 552 for (uint32_t channel = 0; channel < TGSI_NUM_CHANNELS; channel++) { 553 if (!outputs[attrib][channel]) 554 continue; 555 556 LLVMValueRef out = 557 LLVMBuildLoad(gallivm->builder, outputs[attrib][channel], ""); 558 if (swr_fs->info.base.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS]) { 559 for (uint32_t rt = 0; rt < key.nr_cbufs; rt++) { 560 STORE(unwrap(out), 561 pPS, 562 {0, SWR_PS_CONTEXT_shaded, rt, channel}); 563 } 564 } else { 565 STORE(unwrap(out), 566 pPS, 567 {0, 568 SWR_PS_CONTEXT_shaded, 569 swr_fs->info.base.output_semantic_index[attrib], 570 channel}); 571 } 572 } 573 break; 574 } 575 default: { 576 fprintf(stderr, 577 "unknown output from FS %s[%d]\n", 578 tgsi_semantic_names[swr_fs->info.base 579 .output_semantic_name[attrib]], 580 swr_fs->info.base.output_semantic_index[attrib]); 581 break; 582 } 583 } 584 } 585 586 LLVMValueRef mask_result = 0; 587 if (swr_fs->info.base.uses_kill) { 588 mask_result = lp_build_mask_end(&mask); 589 } 590 591 IRB()->SetInsertPoint(unwrap(LLVMGetInsertBlock(gallivm->builder))); 592 593 if (swr_fs->info.base.uses_kill) { 594 STORE(unwrap(mask_result), pPS, {0, SWR_PS_CONTEXT_activeMask}); 595 } 596 597 RET_VOID(); 598 599 gallivm_verify_function(gallivm, wrap(pFunction)); 600 601 gallivm_compile_module(gallivm); 602 603 PFN_PIXEL_KERNEL kernel = 604 (PFN_PIXEL_KERNEL)gallivm_jit_function(gallivm, wrap(pFunction)); 605 debug_printf("frag shader %p\n", kernel); 606 assert(kernel && "Error: FragShader = NULL"); 607 608#if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR >= 5) 609 JM()->mIsModuleFinalized = true; 610#endif 611 612 return kernel; 613} 614 615PFN_PIXEL_KERNEL 616swr_compile_fs(struct swr_context *ctx, swr_jit_fs_key &key) 617{ 618 BuilderSWR builder( 619 reinterpret_cast<JitManager *>(swr_screen(ctx->pipe.screen)->hJitMgr)); 620 return builder.CompileFS(ctx, key); 621} 622