1/* 2 * Copyright © 2016 Red Hat. 3 * Copyright © 2016 Bas Nieuwenhuizen 4 * 5 * based in part on anv driver which is: 6 * Copyright © 2015 Intel Corporation 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the next 16 * paragraph) shall be included in all copies or substantial portions of the 17 * Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 * DEALINGS IN THE SOFTWARE. 26 */ 27 28#include "tu_private.h" 29 30#include "main/menums.h" 31#include "nir/nir.h" 32#include "nir/nir_builder.h" 33#include "spirv/nir_spirv.h" 34#include "util/debug.h" 35#include "util/mesa-sha1.h" 36#include "util/u_atomic.h" 37#include "vk_format.h" 38#include "vk_util.h" 39 40#include "tu_cs.h" 41 42struct tu_pipeline_builder 43{ 44 struct tu_device *device; 45 struct tu_pipeline_cache *cache; 46 const VkAllocationCallbacks *alloc; 47 const VkGraphicsPipelineCreateInfo *create_info; 48 49 struct tu_shader *shaders[MESA_SHADER_STAGES]; 50 uint32_t shader_offsets[MESA_SHADER_STAGES]; 51 uint32_t binning_vs_offset; 52 uint32_t shader_total_size; 53 54 bool rasterizer_discard; 55 /* these states are affectd by rasterizer_discard */ 56 VkSampleCountFlagBits samples; 57 bool use_depth_stencil_attachment; 58 bool use_color_attachments; 59 uint32_t color_attachment_count; 60 VkFormat color_attachment_formats[MAX_RTS]; 61}; 62 63static enum tu_dynamic_state_bits 64tu_dynamic_state_bit(VkDynamicState state) 65{ 66 switch (state) { 67 case VK_DYNAMIC_STATE_VIEWPORT: 68 return TU_DYNAMIC_VIEWPORT; 69 case VK_DYNAMIC_STATE_SCISSOR: 70 return TU_DYNAMIC_SCISSOR; 71 case VK_DYNAMIC_STATE_LINE_WIDTH: 72 return TU_DYNAMIC_LINE_WIDTH; 73 case VK_DYNAMIC_STATE_DEPTH_BIAS: 74 return TU_DYNAMIC_DEPTH_BIAS; 75 case VK_DYNAMIC_STATE_BLEND_CONSTANTS: 76 return TU_DYNAMIC_BLEND_CONSTANTS; 77 case VK_DYNAMIC_STATE_DEPTH_BOUNDS: 78 return TU_DYNAMIC_DEPTH_BOUNDS; 79 case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: 80 return TU_DYNAMIC_STENCIL_COMPARE_MASK; 81 case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: 82 return TU_DYNAMIC_STENCIL_WRITE_MASK; 83 case VK_DYNAMIC_STATE_STENCIL_REFERENCE: 84 return TU_DYNAMIC_STENCIL_REFERENCE; 85 default: 86 unreachable("invalid dynamic state"); 87 return 0; 88 } 89} 90 91static gl_shader_stage 92tu_shader_stage(VkShaderStageFlagBits stage) 93{ 94 switch (stage) { 95 case VK_SHADER_STAGE_VERTEX_BIT: 96 return MESA_SHADER_VERTEX; 97 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 98 return MESA_SHADER_TESS_CTRL; 99 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 100 return MESA_SHADER_TESS_EVAL; 101 case VK_SHADER_STAGE_GEOMETRY_BIT: 102 return MESA_SHADER_GEOMETRY; 103 case VK_SHADER_STAGE_FRAGMENT_BIT: 104 return MESA_SHADER_FRAGMENT; 105 case VK_SHADER_STAGE_COMPUTE_BIT: 106 return MESA_SHADER_COMPUTE; 107 default: 108 unreachable("invalid VkShaderStageFlagBits"); 109 return MESA_SHADER_NONE; 110 } 111} 112 113static const VkVertexInputAttributeDescription * 114tu_find_vertex_input_attribute( 115 const VkPipelineVertexInputStateCreateInfo *vi_info, uint32_t slot) 116{ 117 assert(slot >= VERT_ATTRIB_GENERIC0); 118 slot -= VERT_ATTRIB_GENERIC0; 119 for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) { 120 if (vi_info->pVertexAttributeDescriptions[i].location == slot) 121 return &vi_info->pVertexAttributeDescriptions[i]; 122 } 123 return NULL; 124} 125 126static const VkVertexInputBindingDescription * 127tu_find_vertex_input_binding( 128 const VkPipelineVertexInputStateCreateInfo *vi_info, 129 const VkVertexInputAttributeDescription *vi_attr) 130{ 131 assert(vi_attr); 132 for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) { 133 if (vi_info->pVertexBindingDescriptions[i].binding == vi_attr->binding) 134 return &vi_info->pVertexBindingDescriptions[i]; 135 } 136 return NULL; 137} 138 139static bool 140tu_logic_op_reads_dst(VkLogicOp op) 141{ 142 switch (op) { 143 case VK_LOGIC_OP_CLEAR: 144 case VK_LOGIC_OP_COPY: 145 case VK_LOGIC_OP_COPY_INVERTED: 146 case VK_LOGIC_OP_SET: 147 return false; 148 default: 149 return true; 150 } 151} 152 153static VkBlendFactor 154tu_blend_factor_no_dst_alpha(VkBlendFactor factor) 155{ 156 /* treat dst alpha as 1.0 and avoid reading it */ 157 switch (factor) { 158 case VK_BLEND_FACTOR_DST_ALPHA: 159 return VK_BLEND_FACTOR_ONE; 160 case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: 161 return VK_BLEND_FACTOR_ZERO; 162 default: 163 return factor; 164 } 165} 166 167static enum pc_di_primtype 168tu6_primtype(VkPrimitiveTopology topology) 169{ 170 switch (topology) { 171 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 172 return DI_PT_POINTLIST; 173 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 174 return DI_PT_LINELIST; 175 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 176 return DI_PT_LINESTRIP; 177 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 178 return DI_PT_TRILIST; 179 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: 180 return DI_PT_TRILIST; 181 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: 182 return DI_PT_TRIFAN; 183 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 184 return DI_PT_LINE_ADJ; 185 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: 186 return DI_PT_LINESTRIP_ADJ; 187 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 188 return DI_PT_TRI_ADJ; 189 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: 190 return DI_PT_TRISTRIP_ADJ; 191 case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: 192 default: 193 unreachable("invalid primitive topology"); 194 return DI_PT_NONE; 195 } 196} 197 198static enum adreno_compare_func 199tu6_compare_func(VkCompareOp op) 200{ 201 switch (op) { 202 case VK_COMPARE_OP_NEVER: 203 return FUNC_NEVER; 204 case VK_COMPARE_OP_LESS: 205 return FUNC_LESS; 206 case VK_COMPARE_OP_EQUAL: 207 return FUNC_EQUAL; 208 case VK_COMPARE_OP_LESS_OR_EQUAL: 209 return FUNC_LEQUAL; 210 case VK_COMPARE_OP_GREATER: 211 return FUNC_GREATER; 212 case VK_COMPARE_OP_NOT_EQUAL: 213 return FUNC_NOTEQUAL; 214 case VK_COMPARE_OP_GREATER_OR_EQUAL: 215 return FUNC_GEQUAL; 216 case VK_COMPARE_OP_ALWAYS: 217 return FUNC_ALWAYS; 218 default: 219 unreachable("invalid VkCompareOp"); 220 return FUNC_NEVER; 221 } 222} 223 224static enum adreno_stencil_op 225tu6_stencil_op(VkStencilOp op) 226{ 227 switch (op) { 228 case VK_STENCIL_OP_KEEP: 229 return STENCIL_KEEP; 230 case VK_STENCIL_OP_ZERO: 231 return STENCIL_ZERO; 232 case VK_STENCIL_OP_REPLACE: 233 return STENCIL_REPLACE; 234 case VK_STENCIL_OP_INCREMENT_AND_CLAMP: 235 return STENCIL_INCR_CLAMP; 236 case VK_STENCIL_OP_DECREMENT_AND_CLAMP: 237 return STENCIL_DECR_CLAMP; 238 case VK_STENCIL_OP_INVERT: 239 return STENCIL_INVERT; 240 case VK_STENCIL_OP_INCREMENT_AND_WRAP: 241 return STENCIL_INCR_WRAP; 242 case VK_STENCIL_OP_DECREMENT_AND_WRAP: 243 return STENCIL_DECR_WRAP; 244 default: 245 unreachable("invalid VkStencilOp"); 246 return STENCIL_KEEP; 247 } 248} 249 250static enum a3xx_rop_code 251tu6_rop(VkLogicOp op) 252{ 253 switch (op) { 254 case VK_LOGIC_OP_CLEAR: 255 return ROP_CLEAR; 256 case VK_LOGIC_OP_AND: 257 return ROP_AND; 258 case VK_LOGIC_OP_AND_REVERSE: 259 return ROP_AND_REVERSE; 260 case VK_LOGIC_OP_COPY: 261 return ROP_COPY; 262 case VK_LOGIC_OP_AND_INVERTED: 263 return ROP_AND_INVERTED; 264 case VK_LOGIC_OP_NO_OP: 265 return ROP_NOOP; 266 case VK_LOGIC_OP_XOR: 267 return ROP_XOR; 268 case VK_LOGIC_OP_OR: 269 return ROP_OR; 270 case VK_LOGIC_OP_NOR: 271 return ROP_NOR; 272 case VK_LOGIC_OP_EQUIVALENT: 273 return ROP_EQUIV; 274 case VK_LOGIC_OP_INVERT: 275 return ROP_INVERT; 276 case VK_LOGIC_OP_OR_REVERSE: 277 return ROP_OR_REVERSE; 278 case VK_LOGIC_OP_COPY_INVERTED: 279 return ROP_COPY_INVERTED; 280 case VK_LOGIC_OP_OR_INVERTED: 281 return ROP_OR_INVERTED; 282 case VK_LOGIC_OP_NAND: 283 return ROP_NAND; 284 case VK_LOGIC_OP_SET: 285 return ROP_SET; 286 default: 287 unreachable("invalid VkLogicOp"); 288 return ROP_NOOP; 289 } 290} 291 292static enum adreno_rb_blend_factor 293tu6_blend_factor(VkBlendFactor factor) 294{ 295 switch (factor) { 296 case VK_BLEND_FACTOR_ZERO: 297 return FACTOR_ZERO; 298 case VK_BLEND_FACTOR_ONE: 299 return FACTOR_ONE; 300 case VK_BLEND_FACTOR_SRC_COLOR: 301 return FACTOR_SRC_COLOR; 302 case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: 303 return FACTOR_ONE_MINUS_SRC_COLOR; 304 case VK_BLEND_FACTOR_DST_COLOR: 305 return FACTOR_DST_COLOR; 306 case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: 307 return FACTOR_ONE_MINUS_DST_COLOR; 308 case VK_BLEND_FACTOR_SRC_ALPHA: 309 return FACTOR_SRC_ALPHA; 310 case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: 311 return FACTOR_ONE_MINUS_SRC_ALPHA; 312 case VK_BLEND_FACTOR_DST_ALPHA: 313 return FACTOR_DST_ALPHA; 314 case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: 315 return FACTOR_ONE_MINUS_DST_ALPHA; 316 case VK_BLEND_FACTOR_CONSTANT_COLOR: 317 return FACTOR_CONSTANT_COLOR; 318 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: 319 return FACTOR_ONE_MINUS_CONSTANT_COLOR; 320 case VK_BLEND_FACTOR_CONSTANT_ALPHA: 321 return FACTOR_CONSTANT_ALPHA; 322 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: 323 return FACTOR_ONE_MINUS_CONSTANT_ALPHA; 324 case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: 325 return FACTOR_SRC_ALPHA_SATURATE; 326 case VK_BLEND_FACTOR_SRC1_COLOR: 327 return FACTOR_SRC1_COLOR; 328 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: 329 return FACTOR_ONE_MINUS_SRC1_COLOR; 330 case VK_BLEND_FACTOR_SRC1_ALPHA: 331 return FACTOR_SRC1_ALPHA; 332 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: 333 return FACTOR_ONE_MINUS_SRC1_ALPHA; 334 default: 335 unreachable("invalid VkBlendFactor"); 336 return FACTOR_ZERO; 337 } 338} 339 340static enum a3xx_rb_blend_opcode 341tu6_blend_op(VkBlendOp op) 342{ 343 switch (op) { 344 case VK_BLEND_OP_ADD: 345 return BLEND_DST_PLUS_SRC; 346 case VK_BLEND_OP_SUBTRACT: 347 return BLEND_SRC_MINUS_DST; 348 case VK_BLEND_OP_REVERSE_SUBTRACT: 349 return BLEND_DST_MINUS_SRC; 350 case VK_BLEND_OP_MIN: 351 return BLEND_MIN_DST_SRC; 352 case VK_BLEND_OP_MAX: 353 return BLEND_MAX_DST_SRC; 354 default: 355 unreachable("invalid VkBlendOp"); 356 return BLEND_DST_PLUS_SRC; 357 } 358} 359 360static void 361tu6_emit_vs_config(struct tu_cs *cs, const struct ir3_shader_variant *vs) 362{ 363 uint32_t sp_vs_ctrl = 364 A6XX_SP_VS_CTRL_REG0_THREADSIZE(FOUR_QUADS) | 365 A6XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT(vs->info.max_reg + 1) | 366 A6XX_SP_VS_CTRL_REG0_MERGEDREGS | 367 A6XX_SP_VS_CTRL_REG0_BRANCHSTACK(vs->branchstack); 368 if (vs->num_samp) 369 sp_vs_ctrl |= A6XX_SP_VS_CTRL_REG0_PIXLODENABLE; 370 371 uint32_t sp_vs_config = A6XX_SP_VS_CONFIG_NTEX(vs->num_samp) | 372 A6XX_SP_VS_CONFIG_NSAMP(vs->num_samp); 373 if (vs->instrlen) 374 sp_vs_config |= A6XX_SP_VS_CONFIG_ENABLED; 375 376 tu_cs_emit_pkt4(cs, REG_A6XX_SP_VS_CTRL_REG0, 1); 377 tu_cs_emit(cs, sp_vs_ctrl); 378 379 tu_cs_emit_pkt4(cs, REG_A6XX_SP_VS_CONFIG, 2); 380 tu_cs_emit(cs, sp_vs_config); 381 tu_cs_emit(cs, vs->instrlen); 382 383 tu_cs_emit_pkt4(cs, REG_A6XX_HLSQ_VS_CNTL, 1); 384 tu_cs_emit(cs, A6XX_HLSQ_VS_CNTL_CONSTLEN(align(vs->constlen, 4)) | 0x100); 385} 386 387static void 388tu6_emit_hs_config(struct tu_cs *cs, const struct ir3_shader_variant *hs) 389{ 390 uint32_t sp_hs_config = 0; 391 if (hs->instrlen) 392 sp_hs_config |= A6XX_SP_HS_CONFIG_ENABLED; 393 394 tu_cs_emit_pkt4(cs, REG_A6XX_SP_HS_UNKNOWN_A831, 1); 395 tu_cs_emit(cs, 0); 396 397 tu_cs_emit_pkt4(cs, REG_A6XX_SP_HS_CONFIG, 2); 398 tu_cs_emit(cs, sp_hs_config); 399 tu_cs_emit(cs, hs->instrlen); 400 401 tu_cs_emit_pkt4(cs, REG_A6XX_HLSQ_HS_CNTL, 1); 402 tu_cs_emit(cs, A6XX_HLSQ_HS_CNTL_CONSTLEN(align(hs->constlen, 4))); 403} 404 405static void 406tu6_emit_ds_config(struct tu_cs *cs, const struct ir3_shader_variant *ds) 407{ 408 uint32_t sp_ds_config = 0; 409 if (ds->instrlen) 410 sp_ds_config |= A6XX_SP_DS_CONFIG_ENABLED; 411 412 tu_cs_emit_pkt4(cs, REG_A6XX_SP_DS_CONFIG, 2); 413 tu_cs_emit(cs, sp_ds_config); 414 tu_cs_emit(cs, ds->instrlen); 415 416 tu_cs_emit_pkt4(cs, REG_A6XX_HLSQ_DS_CNTL, 1); 417 tu_cs_emit(cs, A6XX_HLSQ_DS_CNTL_CONSTLEN(align(ds->constlen, 4))); 418} 419 420static void 421tu6_emit_gs_config(struct tu_cs *cs, const struct ir3_shader_variant *gs) 422{ 423 uint32_t sp_gs_config = 0; 424 if (gs->instrlen) 425 sp_gs_config |= A6XX_SP_GS_CONFIG_ENABLED; 426 427 tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_UNKNOWN_A871, 1); 428 tu_cs_emit(cs, 0); 429 430 tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_CONFIG, 2); 431 tu_cs_emit(cs, sp_gs_config); 432 tu_cs_emit(cs, gs->instrlen); 433 434 tu_cs_emit_pkt4(cs, REG_A6XX_HLSQ_GS_CNTL, 1); 435 tu_cs_emit(cs, A6XX_HLSQ_GS_CNTL_CONSTLEN(align(gs->constlen, 4))); 436} 437 438static void 439tu6_emit_fs_config(struct tu_cs *cs, const struct ir3_shader_variant *fs) 440{ 441 uint32_t sp_fs_ctrl = 442 A6XX_SP_FS_CTRL_REG0_THREADSIZE(FOUR_QUADS) | 0x1000000 | 443 A6XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT(fs->info.max_reg + 1) | 444 A6XX_SP_FS_CTRL_REG0_MERGEDREGS | 445 A6XX_SP_FS_CTRL_REG0_BRANCHSTACK(fs->branchstack); 446 if (fs->total_in > 0 || fs->frag_coord) 447 sp_fs_ctrl |= A6XX_SP_FS_CTRL_REG0_VARYING; 448 if (fs->num_samp > 0) 449 sp_fs_ctrl |= A6XX_SP_FS_CTRL_REG0_PIXLODENABLE; 450 451 uint32_t sp_fs_config = A6XX_SP_FS_CONFIG_NTEX(fs->num_samp) | 452 A6XX_SP_FS_CONFIG_NSAMP(fs->num_samp); 453 if (fs->instrlen) 454 sp_fs_config |= A6XX_SP_FS_CONFIG_ENABLED; 455 456 tu_cs_emit_pkt4(cs, REG_A6XX_SP_UNKNOWN_A99E, 1); 457 tu_cs_emit(cs, 0x7fc0); 458 459 tu_cs_emit_pkt4(cs, REG_A6XX_SP_UNKNOWN_A9A8, 1); 460 tu_cs_emit(cs, 0); 461 462 tu_cs_emit_pkt4(cs, REG_A6XX_SP_UNKNOWN_AB00, 1); 463 tu_cs_emit(cs, 0x5); 464 465 tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_CTRL_REG0, 1); 466 tu_cs_emit(cs, sp_fs_ctrl); 467 468 tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_CONFIG, 2); 469 tu_cs_emit(cs, sp_fs_config); 470 tu_cs_emit(cs, fs->instrlen); 471 472 tu_cs_emit_pkt4(cs, REG_A6XX_HLSQ_FS_CNTL, 1); 473 tu_cs_emit(cs, A6XX_HLSQ_FS_CNTL_CONSTLEN(align(fs->constlen, 4)) | 0x100); 474} 475 476static void 477tu6_emit_vs_system_values(struct tu_cs *cs, 478 const struct ir3_shader_variant *vs) 479{ 480 const uint32_t vertexid_regid = 481 ir3_find_sysval_regid(vs, SYSTEM_VALUE_VERTEX_ID_ZERO_BASE); 482 const uint32_t instanceid_regid = 483 ir3_find_sysval_regid(vs, SYSTEM_VALUE_INSTANCE_ID); 484 485 tu_cs_emit_pkt4(cs, REG_A6XX_VFD_CONTROL_1, 6); 486 tu_cs_emit(cs, A6XX_VFD_CONTROL_1_REGID4VTX(vertexid_regid) | 487 A6XX_VFD_CONTROL_1_REGID4INST(instanceid_regid) | 488 0xfcfc0000); 489 tu_cs_emit(cs, 0x0000fcfc); /* VFD_CONTROL_2 */ 490 tu_cs_emit(cs, 0xfcfcfcfc); /* VFD_CONTROL_3 */ 491 tu_cs_emit(cs, 0x000000fc); /* VFD_CONTROL_4 */ 492 tu_cs_emit(cs, 0x0000fcfc); /* VFD_CONTROL_5 */ 493 tu_cs_emit(cs, 0x00000000); /* VFD_CONTROL_6 */ 494} 495 496static void 497tu6_emit_vpc(struct tu_cs *cs, 498 const struct ir3_shader_variant *vs, 499 const struct ir3_shader_variant *fs, 500 bool binning_pass) 501{ 502 struct ir3_shader_linkage linkage = { 0 }; 503 ir3_link_shaders(&linkage, vs, fs); 504 505 if (vs->shader->stream_output.num_outputs && !binning_pass) 506 tu_finishme("stream output"); 507 508 BITSET_DECLARE(vpc_var_enables, 128) = { 0 }; 509 for (uint32_t i = 0; i < linkage.cnt; i++) { 510 const uint32_t comp_count = util_last_bit(linkage.var[i].compmask); 511 for (uint32_t j = 0; j < comp_count; j++) 512 BITSET_SET(vpc_var_enables, linkage.var[i].loc + j); 513 } 514 515 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_VAR_DISABLE(0), 4); 516 tu_cs_emit(cs, ~vpc_var_enables[0]); 517 tu_cs_emit(cs, ~vpc_var_enables[1]); 518 tu_cs_emit(cs, ~vpc_var_enables[2]); 519 tu_cs_emit(cs, ~vpc_var_enables[3]); 520 521 /* a6xx finds position/pointsize at the end */ 522 const uint32_t position_regid = 523 ir3_find_output_regid(vs, VARYING_SLOT_POS); 524 const uint32_t pointsize_regid = 525 ir3_find_output_regid(vs, VARYING_SLOT_PSIZ); 526 uint32_t pointsize_loc = 0xff; 527 if (position_regid != regid(63, 0)) 528 ir3_link_add(&linkage, position_regid, 0xf, linkage.max_loc); 529 if (pointsize_regid != regid(63, 0)) { 530 pointsize_loc = linkage.max_loc; 531 ir3_link_add(&linkage, pointsize_regid, 0x1, linkage.max_loc); 532 } 533 534 /* map vs outputs to VPC */ 535 assert(linkage.cnt <= 32); 536 const uint32_t sp_vs_out_count = (linkage.cnt + 1) / 2; 537 const uint32_t sp_vs_vpc_dst_count = (linkage.cnt + 3) / 4; 538 uint32_t sp_vs_out[16]; 539 uint32_t sp_vs_vpc_dst[8]; 540 sp_vs_out[sp_vs_out_count - 1] = 0; 541 sp_vs_vpc_dst[sp_vs_vpc_dst_count - 1] = 0; 542 for (uint32_t i = 0; i < linkage.cnt; i++) { 543 ((uint16_t *) sp_vs_out)[i] = 544 A6XX_SP_VS_OUT_REG_A_REGID(linkage.var[i].regid) | 545 A6XX_SP_VS_OUT_REG_A_COMPMASK(linkage.var[i].compmask); 546 ((uint8_t *) sp_vs_vpc_dst)[i] = 547 A6XX_SP_VS_VPC_DST_REG_OUTLOC0(linkage.var[i].loc); 548 } 549 550 tu_cs_emit_pkt4(cs, REG_A6XX_SP_VS_OUT_REG(0), sp_vs_out_count); 551 tu_cs_emit_array(cs, sp_vs_out, sp_vs_out_count); 552 553 tu_cs_emit_pkt4(cs, REG_A6XX_SP_VS_VPC_DST_REG(0), sp_vs_vpc_dst_count); 554 tu_cs_emit_array(cs, sp_vs_vpc_dst, sp_vs_vpc_dst_count); 555 556 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_CNTL_0, 1); 557 tu_cs_emit(cs, A6XX_VPC_CNTL_0_NUMNONPOSVAR(fs->total_in) | 558 (fs->total_in > 0 ? A6XX_VPC_CNTL_0_VARYING : 0) | 559 0xff00ff00); 560 561 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_PACK, 1); 562 tu_cs_emit(cs, A6XX_VPC_PACK_NUMNONPOSVAR(fs->total_in) | 563 A6XX_VPC_PACK_PSIZELOC(pointsize_loc) | 564 A6XX_VPC_PACK_STRIDE_IN_VPC(linkage.max_loc)); 565 566 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_GS_SIV_CNTL, 1); 567 tu_cs_emit(cs, 0x0000ffff); /* XXX */ 568 569 tu_cs_emit_pkt4(cs, REG_A6XX_SP_PRIMITIVE_CNTL, 1); 570 tu_cs_emit(cs, A6XX_SP_PRIMITIVE_CNTL_VSOUT(linkage.cnt)); 571 572 tu_cs_emit_pkt4(cs, REG_A6XX_PC_PRIMITIVE_CNTL_1, 1); 573 tu_cs_emit(cs, A6XX_PC_PRIMITIVE_CNTL_1_STRIDE_IN_VPC(linkage.max_loc) | 574 (vs->writes_psize ? A6XX_PC_PRIMITIVE_CNTL_1_PSIZE : 0)); 575} 576 577static int 578tu6_vpc_varying_mode(const struct ir3_shader_variant *fs, 579 uint32_t index, 580 uint8_t *interp_mode, 581 uint8_t *ps_repl_mode) 582{ 583 enum 584 { 585 INTERP_SMOOTH = 0, 586 INTERP_FLAT = 1, 587 INTERP_ZERO = 2, 588 INTERP_ONE = 3, 589 }; 590 enum 591 { 592 PS_REPL_NONE = 0, 593 PS_REPL_S = 1, 594 PS_REPL_T = 2, 595 PS_REPL_ONE_MINUS_T = 3, 596 }; 597 598 const uint32_t compmask = fs->inputs[index].compmask; 599 600 /* NOTE: varyings are packed, so if compmask is 0xb then first, second, and 601 * fourth component occupy three consecutive varying slots 602 */ 603 int shift = 0; 604 *interp_mode = 0; 605 *ps_repl_mode = 0; 606 if (fs->inputs[index].slot == VARYING_SLOT_PNTC) { 607 if (compmask & 0x1) { 608 *ps_repl_mode |= PS_REPL_S << shift; 609 shift += 2; 610 } 611 if (compmask & 0x2) { 612 *ps_repl_mode |= PS_REPL_T << shift; 613 shift += 2; 614 } 615 if (compmask & 0x4) { 616 *interp_mode |= INTERP_ZERO << shift; 617 shift += 2; 618 } 619 if (compmask & 0x8) { 620 *interp_mode |= INTERP_ONE << 6; 621 shift += 2; 622 } 623 } else if ((fs->inputs[index].interpolate == INTERP_MODE_FLAT) || 624 fs->inputs[index].rasterflat) { 625 for (int i = 0; i < 4; i++) { 626 if (compmask & (1 << i)) { 627 *interp_mode |= INTERP_FLAT << shift; 628 shift += 2; 629 } 630 } 631 } 632 633 return shift; 634} 635 636static void 637tu6_emit_vpc_varying_modes(struct tu_cs *cs, 638 const struct ir3_shader_variant *fs, 639 bool binning_pass) 640{ 641 uint32_t interp_modes[8] = { 0 }; 642 uint32_t ps_repl_modes[8] = { 0 }; 643 644 if (!binning_pass) { 645 for (int i = -1; 646 (i = ir3_next_varying(fs, i)) < (int) fs->inputs_count;) { 647 648 /* get the mode for input i */ 649 uint8_t interp_mode; 650 uint8_t ps_repl_mode; 651 const int bits = 652 tu6_vpc_varying_mode(fs, i, &interp_mode, &ps_repl_mode); 653 654 /* OR the mode into the array */ 655 const uint32_t inloc = fs->inputs[i].inloc * 2; 656 uint32_t n = inloc / 32; 657 uint32_t shift = inloc % 32; 658 interp_modes[n] |= interp_mode << shift; 659 ps_repl_modes[n] |= ps_repl_mode << shift; 660 if (shift + bits > 32) { 661 n++; 662 shift = 32 - shift; 663 664 interp_modes[n] |= interp_mode >> shift; 665 ps_repl_modes[n] |= ps_repl_mode >> shift; 666 } 667 } 668 } 669 670 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_VARYING_INTERP_MODE(0), 8); 671 tu_cs_emit_array(cs, interp_modes, 8); 672 673 tu_cs_emit_pkt4(cs, REG_A6XX_VPC_VARYING_PS_REPL_MODE(0), 8); 674 tu_cs_emit_array(cs, ps_repl_modes, 8); 675} 676 677static void 678tu6_emit_fs_system_values(struct tu_cs *cs, 679 const struct ir3_shader_variant *fs) 680{ 681 const uint32_t frontfacing_regid = 682 ir3_find_sysval_regid(fs, SYSTEM_VALUE_FRONT_FACE); 683 const uint32_t sampleid_regid = 684 ir3_find_sysval_regid(fs, SYSTEM_VALUE_SAMPLE_ID); 685 const uint32_t samplemaskin_regid = 686 ir3_find_sysval_regid(fs, SYSTEM_VALUE_SAMPLE_MASK_IN); 687 const uint32_t fragcoord_xy_regid = 688 ir3_find_sysval_regid(fs, SYSTEM_VALUE_FRAG_COORD); 689 const uint32_t fragcoord_zw_regid = (fragcoord_xy_regid != regid(63, 0)) 690 ? (fragcoord_xy_regid + 2) 691 : fragcoord_xy_regid; 692 const uint32_t varyingcoord_regid = 693 ir3_find_sysval_regid(fs, SYSTEM_VALUE_BARYCENTRIC_PIXEL); 694 695 tu_cs_emit_pkt4(cs, REG_A6XX_HLSQ_CONTROL_1_REG, 5); 696 tu_cs_emit(cs, 0x7); 697 tu_cs_emit(cs, A6XX_HLSQ_CONTROL_2_REG_FACEREGID(frontfacing_regid) | 698 A6XX_HLSQ_CONTROL_2_REG_SAMPLEID(sampleid_regid) | 699 A6XX_HLSQ_CONTROL_2_REG_SAMPLEMASK(samplemaskin_regid) | 700 A6XX_HLSQ_CONTROL_2_REG_SIZE(regid(63, 0))); 701 tu_cs_emit(cs, 702 A6XX_HLSQ_CONTROL_3_REG_BARY_IJ_PIXEL(varyingcoord_regid) | 703 A6XX_HLSQ_CONTROL_3_REG_BARY_IJ_CENTROID(regid(63, 0)) | 704 0xfc00fc00); 705 tu_cs_emit(cs, 706 A6XX_HLSQ_CONTROL_4_REG_XYCOORDREGID(fragcoord_xy_regid) | 707 A6XX_HLSQ_CONTROL_4_REG_ZWCOORDREGID(fragcoord_zw_regid) | 708 A6XX_HLSQ_CONTROL_4_REG_BARY_IJ_PIXEL_PERSAMP(regid(63, 0)) | 709 0x0000fc00); 710 tu_cs_emit(cs, 0xfc); 711} 712 713static void 714tu6_emit_fs_inputs(struct tu_cs *cs, const struct ir3_shader_variant *fs) 715{ 716 tu_cs_emit_pkt4(cs, REG_A6XX_HLSQ_UNKNOWN_B980, 1); 717 tu_cs_emit(cs, fs->total_in > 0 ? 3 : 1); 718 719 tu_cs_emit_pkt4(cs, REG_A6XX_SP_UNKNOWN_A982, 1); 720 tu_cs_emit(cs, 0); /* XXX */ 721 722 tu_cs_emit_pkt4(cs, REG_A6XX_HLSQ_UPDATE_CNTL, 1); 723 tu_cs_emit(cs, 0xff); /* XXX */ 724 725 uint32_t gras_cntl = 0; 726 if (fs->total_in > 0) 727 gras_cntl |= A6XX_GRAS_CNTL_VARYING; 728 if (fs->frag_coord) { 729 gras_cntl |= A6XX_GRAS_CNTL_SIZE | A6XX_GRAS_CNTL_XCOORD | 730 A6XX_GRAS_CNTL_YCOORD | A6XX_GRAS_CNTL_ZCOORD | 731 A6XX_GRAS_CNTL_WCOORD; 732 } 733 734 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_CNTL, 1); 735 tu_cs_emit(cs, gras_cntl); 736 737 uint32_t rb_render_control = 0; 738 if (fs->total_in > 0) { 739 rb_render_control = 740 A6XX_RB_RENDER_CONTROL0_VARYING | A6XX_RB_RENDER_CONTROL0_UNK10; 741 } 742 if (fs->frag_coord) { 743 rb_render_control |= 744 A6XX_RB_RENDER_CONTROL0_SIZE | A6XX_RB_RENDER_CONTROL0_XCOORD | 745 A6XX_RB_RENDER_CONTROL0_YCOORD | A6XX_RB_RENDER_CONTROL0_ZCOORD | 746 A6XX_RB_RENDER_CONTROL0_WCOORD; 747 } 748 749 tu_cs_emit_pkt4(cs, REG_A6XX_RB_RENDER_CONTROL0, 2); 750 tu_cs_emit(cs, rb_render_control); 751 tu_cs_emit(cs, (fs->frag_face ? A6XX_RB_RENDER_CONTROL1_FACENESS : 0)); 752} 753 754static void 755tu6_emit_fs_outputs(struct tu_cs *cs, 756 const struct ir3_shader_variant *fs, 757 uint32_t mrt_count) 758{ 759 const uint32_t fragdepth_regid = 760 ir3_find_output_regid(fs, FRAG_RESULT_DEPTH); 761 uint32_t fragdata_regid[8]; 762 if (fs->color0_mrt) { 763 fragdata_regid[0] = ir3_find_output_regid(fs, FRAG_RESULT_COLOR); 764 for (uint32_t i = 1; i < ARRAY_SIZE(fragdata_regid); i++) 765 fragdata_regid[i] = fragdata_regid[0]; 766 } else { 767 for (uint32_t i = 0; i < ARRAY_SIZE(fragdata_regid); i++) 768 fragdata_regid[i] = ir3_find_output_regid(fs, FRAG_RESULT_DATA0 + i); 769 } 770 771 tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_OUTPUT_CNTL0, 2); 772 tu_cs_emit( 773 cs, A6XX_SP_FS_OUTPUT_CNTL0_DEPTH_REGID(fragdepth_regid) | 0xfcfc0000); 774 tu_cs_emit(cs, A6XX_SP_FS_OUTPUT_CNTL1_MRT(mrt_count)); 775 776 tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_OUTPUT_REG(0), 8); 777 for (uint32_t i = 0; i < ARRAY_SIZE(fragdata_regid); i++) { 778 // TODO we could have a mix of half and full precision outputs, 779 // we really need to figure out half-precision from IR3_REG_HALF 780 tu_cs_emit(cs, A6XX_SP_FS_OUTPUT_REG_REGID(fragdata_regid[i]) | 781 (false ? A6XX_SP_FS_OUTPUT_REG_HALF_PRECISION : 0)); 782 } 783 784 tu_cs_emit_pkt4(cs, REG_A6XX_RB_FS_OUTPUT_CNTL0, 2); 785 tu_cs_emit(cs, fs->writes_pos ? A6XX_RB_FS_OUTPUT_CNTL0_FRAG_WRITES_Z : 0); 786 tu_cs_emit(cs, A6XX_RB_FS_OUTPUT_CNTL1_MRT(mrt_count)); 787 788 uint32_t gras_su_depth_plane_cntl = 0; 789 uint32_t rb_depth_plane_cntl = 0; 790 if (fs->no_earlyz | fs->writes_pos) { 791 gras_su_depth_plane_cntl |= A6XX_GRAS_SU_DEPTH_PLANE_CNTL_FRAG_WRITES_Z; 792 rb_depth_plane_cntl |= A6XX_RB_DEPTH_PLANE_CNTL_FRAG_WRITES_Z; 793 } 794 795 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_DEPTH_PLANE_CNTL, 1); 796 tu_cs_emit(cs, gras_su_depth_plane_cntl); 797 798 tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_PLANE_CNTL, 1); 799 tu_cs_emit(cs, rb_depth_plane_cntl); 800} 801 802static void 803tu6_emit_shader_object(struct tu_cs *cs, 804 gl_shader_stage stage, 805 const struct ir3_shader_variant *variant, 806 const struct tu_bo *binary_bo, 807 uint32_t binary_offset) 808{ 809 uint16_t reg; 810 uint8_t opcode; 811 enum a6xx_state_block sb; 812 switch (stage) { 813 case MESA_SHADER_VERTEX: 814 reg = REG_A6XX_SP_VS_OBJ_START_LO; 815 opcode = CP_LOAD_STATE6_GEOM; 816 sb = SB6_VS_SHADER; 817 break; 818 case MESA_SHADER_TESS_CTRL: 819 reg = REG_A6XX_SP_HS_OBJ_START_LO; 820 opcode = CP_LOAD_STATE6_GEOM; 821 sb = SB6_HS_SHADER; 822 break; 823 case MESA_SHADER_TESS_EVAL: 824 reg = REG_A6XX_SP_DS_OBJ_START_LO; 825 opcode = CP_LOAD_STATE6_GEOM; 826 sb = SB6_DS_SHADER; 827 break; 828 case MESA_SHADER_GEOMETRY: 829 reg = REG_A6XX_SP_GS_OBJ_START_LO; 830 opcode = CP_LOAD_STATE6_GEOM; 831 sb = SB6_GS_SHADER; 832 break; 833 case MESA_SHADER_FRAGMENT: 834 reg = REG_A6XX_SP_FS_OBJ_START_LO; 835 opcode = CP_LOAD_STATE6_FRAG; 836 sb = SB6_FS_SHADER; 837 break; 838 case MESA_SHADER_COMPUTE: 839 reg = REG_A6XX_SP_CS_OBJ_START_LO; 840 opcode = CP_LOAD_STATE6_FRAG; 841 sb = SB6_CS_SHADER; 842 break; 843 default: 844 unreachable("invalid gl_shader_stage"); 845 opcode = CP_LOAD_STATE6_GEOM; 846 sb = SB6_VS_SHADER; 847 break; 848 } 849 850 if (!variant->instrlen) { 851 tu_cs_emit_pkt4(cs, reg, 2); 852 tu_cs_emit_qw(cs, 0); 853 return; 854 } 855 856 assert(variant->type == stage); 857 858 const uint64_t binary_iova = binary_bo->iova + binary_offset; 859 assert((binary_iova & 0x3) == 0); 860 861 tu_cs_emit_pkt4(cs, reg, 2); 862 tu_cs_emit_qw(cs, binary_iova); 863 864 /* always indirect */ 865 const bool indirect = true; 866 if (indirect) { 867 tu_cs_emit_pkt7(cs, opcode, 3); 868 tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(0) | 869 CP_LOAD_STATE6_0_STATE_TYPE(ST6_SHADER) | 870 CP_LOAD_STATE6_0_STATE_SRC(SS6_INDIRECT) | 871 CP_LOAD_STATE6_0_STATE_BLOCK(sb) | 872 CP_LOAD_STATE6_0_NUM_UNIT(variant->instrlen)); 873 tu_cs_emit_qw(cs, binary_iova); 874 } else { 875 const void *binary = binary_bo->map + binary_offset; 876 877 tu_cs_emit_pkt7(cs, opcode, 3 + variant->info.sizedwords); 878 tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(0) | 879 CP_LOAD_STATE6_0_STATE_TYPE(ST6_SHADER) | 880 CP_LOAD_STATE6_0_STATE_SRC(SS6_DIRECT) | 881 CP_LOAD_STATE6_0_STATE_BLOCK(sb) | 882 CP_LOAD_STATE6_0_NUM_UNIT(variant->instrlen)); 883 tu_cs_emit_qw(cs, 0); 884 tu_cs_emit_array(cs, binary, variant->info.sizedwords); 885 } 886} 887 888static void 889tu6_emit_program(struct tu_cs *cs, 890 const struct tu_pipeline_builder *builder, 891 const struct tu_bo *binary_bo, 892 bool binning_pass) 893{ 894 static const struct ir3_shader_variant dummy_variant = { 895 .type = MESA_SHADER_NONE 896 }; 897 assert(builder->shaders[MESA_SHADER_VERTEX]); 898 const struct ir3_shader_variant *vs = 899 &builder->shaders[MESA_SHADER_VERTEX]->variants[0]; 900 const struct ir3_shader_variant *hs = 901 builder->shaders[MESA_SHADER_TESS_CTRL] 902 ? &builder->shaders[MESA_SHADER_TESS_CTRL]->variants[0] 903 : &dummy_variant; 904 const struct ir3_shader_variant *ds = 905 builder->shaders[MESA_SHADER_TESS_EVAL] 906 ? &builder->shaders[MESA_SHADER_TESS_EVAL]->variants[0] 907 : &dummy_variant; 908 const struct ir3_shader_variant *gs = 909 builder->shaders[MESA_SHADER_GEOMETRY] 910 ? &builder->shaders[MESA_SHADER_GEOMETRY]->variants[0] 911 : &dummy_variant; 912 const struct ir3_shader_variant *fs = 913 builder->shaders[MESA_SHADER_FRAGMENT] 914 ? &builder->shaders[MESA_SHADER_FRAGMENT]->variants[0] 915 : &dummy_variant; 916 917 if (binning_pass) { 918 vs = &builder->shaders[MESA_SHADER_VERTEX]->variants[1]; 919 fs = &dummy_variant; 920 } 921 922 tu6_emit_vs_config(cs, vs); 923 tu6_emit_hs_config(cs, hs); 924 tu6_emit_ds_config(cs, ds); 925 tu6_emit_gs_config(cs, gs); 926 tu6_emit_fs_config(cs, fs); 927 928 tu6_emit_vs_system_values(cs, vs); 929 tu6_emit_vpc(cs, vs, fs, binning_pass); 930 tu6_emit_vpc_varying_modes(cs, fs, binning_pass); 931 tu6_emit_fs_system_values(cs, fs); 932 tu6_emit_fs_inputs(cs, fs); 933 tu6_emit_fs_outputs(cs, fs, builder->color_attachment_count); 934 935 tu6_emit_shader_object(cs, MESA_SHADER_VERTEX, vs, binary_bo, 936 builder->shader_offsets[MESA_SHADER_VERTEX]); 937 938 tu6_emit_shader_object(cs, MESA_SHADER_FRAGMENT, fs, binary_bo, 939 builder->shader_offsets[MESA_SHADER_FRAGMENT]); 940} 941 942static void 943tu6_emit_vertex_input(struct tu_cs *cs, 944 const struct ir3_shader_variant *vs, 945 const VkPipelineVertexInputStateCreateInfo *vi_info, 946 uint8_t bindings[MAX_VERTEX_ATTRIBS], 947 uint16_t strides[MAX_VERTEX_ATTRIBS], 948 uint16_t offsets[MAX_VERTEX_ATTRIBS], 949 uint32_t *count) 950{ 951 uint32_t vfd_decode_idx = 0; 952 953 /* why do we go beyond inputs_count? */ 954 assert(vs->inputs_count + 1 <= MAX_VERTEX_ATTRIBS); 955 for (uint32_t i = 0; i <= vs->inputs_count; i++) { 956 if (vs->inputs[i].sysval || !vs->inputs[i].compmask) 957 continue; 958 959 const VkVertexInputAttributeDescription *vi_attr = 960 tu_find_vertex_input_attribute(vi_info, vs->inputs[i].slot); 961 const VkVertexInputBindingDescription *vi_binding = 962 tu_find_vertex_input_binding(vi_info, vi_attr); 963 assert(vi_attr && vi_binding); 964 965 const struct tu_native_format *format = 966 tu6_get_native_format(vi_attr->format); 967 assert(format && format->vtx >= 0); 968 969 uint32_t vfd_decode = A6XX_VFD_DECODE_INSTR_IDX(vfd_decode_idx) | 970 A6XX_VFD_DECODE_INSTR_FORMAT(format->vtx) | 971 A6XX_VFD_DECODE_INSTR_SWAP(format->swap) | 972 A6XX_VFD_DECODE_INSTR_UNK30; 973 if (vi_binding->inputRate == VK_VERTEX_INPUT_RATE_INSTANCE) 974 vfd_decode |= A6XX_VFD_DECODE_INSTR_INSTANCED; 975 if (!vk_format_is_int(vi_attr->format)) 976 vfd_decode |= A6XX_VFD_DECODE_INSTR_FLOAT; 977 978 const uint32_t vfd_decode_step_rate = 1; 979 980 const uint32_t vfd_dest_cntl = 981 A6XX_VFD_DEST_CNTL_INSTR_WRITEMASK(vs->inputs[i].compmask) | 982 A6XX_VFD_DEST_CNTL_INSTR_REGID(vs->inputs[i].regid); 983 984 tu_cs_emit_pkt4(cs, REG_A6XX_VFD_DECODE(vfd_decode_idx), 2); 985 tu_cs_emit(cs, vfd_decode); 986 tu_cs_emit(cs, vfd_decode_step_rate); 987 988 tu_cs_emit_pkt4(cs, REG_A6XX_VFD_DEST_CNTL(vfd_decode_idx), 1); 989 tu_cs_emit(cs, vfd_dest_cntl); 990 991 bindings[vfd_decode_idx] = vi_binding->binding; 992 strides[vfd_decode_idx] = vi_binding->stride; 993 offsets[vfd_decode_idx] = vi_attr->offset; 994 995 vfd_decode_idx++; 996 } 997 998 tu_cs_emit_pkt4(cs, REG_A6XX_VFD_CONTROL_0, 1); 999 tu_cs_emit( 1000 cs, A6XX_VFD_CONTROL_0_VTXCNT(vfd_decode_idx) | (vfd_decode_idx << 8)); 1001 1002 *count = vfd_decode_idx; 1003} 1004 1005static uint32_t 1006tu6_guardband_adj(uint32_t v) 1007{ 1008 if (v > 256) 1009 return (uint32_t)(511.0 - 65.0 * (log2(v) - 8.0)); 1010 else 1011 return 511; 1012} 1013 1014void 1015tu6_emit_viewport(struct tu_cs *cs, const VkViewport *viewport) 1016{ 1017 float offsets[3]; 1018 float scales[3]; 1019 scales[0] = viewport->width / 2.0f; 1020 scales[1] = viewport->height / 2.0f; 1021 scales[2] = viewport->maxDepth - viewport->minDepth; 1022 offsets[0] = viewport->x + scales[0]; 1023 offsets[1] = viewport->y + scales[1]; 1024 offsets[2] = viewport->minDepth; 1025 1026 VkOffset2D min; 1027 VkOffset2D max; 1028 min.x = (int32_t) viewport->x; 1029 max.x = (int32_t) ceilf(viewport->x + viewport->width); 1030 if (viewport->height >= 0.0f) { 1031 min.y = (int32_t) viewport->y; 1032 max.y = (int32_t) ceilf(viewport->y + viewport->height); 1033 } else { 1034 min.y = (int32_t)(viewport->y + viewport->height); 1035 max.y = (int32_t) ceilf(viewport->y); 1036 } 1037 /* the spec allows viewport->height to be 0.0f */ 1038 if (min.y == max.y) 1039 max.y++; 1040 assert(min.x >= 0 && min.x < max.x); 1041 assert(min.y >= 0 && min.y < max.y); 1042 1043 VkExtent2D guardband_adj; 1044 guardband_adj.width = tu6_guardband_adj(max.x - min.x); 1045 guardband_adj.height = tu6_guardband_adj(max.y - min.y); 1046 1047 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_CL_VPORT_XOFFSET_0, 6); 1048 tu_cs_emit(cs, A6XX_GRAS_CL_VPORT_XOFFSET_0(offsets[0])); 1049 tu_cs_emit(cs, A6XX_GRAS_CL_VPORT_XSCALE_0(scales[0])); 1050 tu_cs_emit(cs, A6XX_GRAS_CL_VPORT_YOFFSET_0(offsets[1])); 1051 tu_cs_emit(cs, A6XX_GRAS_CL_VPORT_YSCALE_0(scales[1])); 1052 tu_cs_emit(cs, A6XX_GRAS_CL_VPORT_ZOFFSET_0(offsets[2])); 1053 tu_cs_emit(cs, A6XX_GRAS_CL_VPORT_ZSCALE_0(scales[2])); 1054 1055 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0, 2); 1056 tu_cs_emit(cs, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(min.x) | 1057 A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(min.y)); 1058 tu_cs_emit(cs, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(max.x - 1) | 1059 A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(max.y - 1)); 1060 1061 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ, 1); 1062 tu_cs_emit(cs, 1063 A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ_HORZ(guardband_adj.width) | 1064 A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ_VERT(guardband_adj.height)); 1065} 1066 1067void 1068tu6_emit_scissor(struct tu_cs *cs, const VkRect2D *scissor) 1069{ 1070 const VkOffset2D min = scissor->offset; 1071 const VkOffset2D max = { 1072 scissor->offset.x + scissor->extent.width, 1073 scissor->offset.y + scissor->extent.height, 1074 }; 1075 1076 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0, 2); 1077 tu_cs_emit(cs, A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0_X(min.x) | 1078 A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0_Y(min.y)); 1079 tu_cs_emit(cs, A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0_X(max.x - 1) | 1080 A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0_Y(max.y - 1)); 1081} 1082 1083static void 1084tu6_emit_gras_unknowns(struct tu_cs *cs) 1085{ 1086 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_UNKNOWN_8000, 1); 1087 tu_cs_emit(cs, 0x80); 1088 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_UNKNOWN_8001, 1); 1089 tu_cs_emit(cs, 0x0); 1090 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_UNKNOWN_8004, 1); 1091 tu_cs_emit(cs, 0x0); 1092} 1093 1094static void 1095tu6_emit_point_size(struct tu_cs *cs) 1096{ 1097 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_POINT_MINMAX, 2); 1098 tu_cs_emit(cs, A6XX_GRAS_SU_POINT_MINMAX_MIN(1.0f / 16.0f) | 1099 A6XX_GRAS_SU_POINT_MINMAX_MAX(4092.0f)); 1100 tu_cs_emit(cs, A6XX_GRAS_SU_POINT_SIZE(1.0f)); 1101} 1102 1103static uint32_t 1104tu6_gras_su_cntl(const VkPipelineRasterizationStateCreateInfo *rast_info, 1105 VkSampleCountFlagBits samples) 1106{ 1107 uint32_t gras_su_cntl = 0; 1108 1109 if (rast_info->cullMode & VK_CULL_MODE_FRONT_BIT) 1110 gras_su_cntl |= A6XX_GRAS_SU_CNTL_CULL_FRONT; 1111 if (rast_info->cullMode & VK_CULL_MODE_BACK_BIT) 1112 gras_su_cntl |= A6XX_GRAS_SU_CNTL_CULL_BACK; 1113 1114 if (rast_info->frontFace == VK_FRONT_FACE_CLOCKWISE) 1115 gras_su_cntl |= A6XX_GRAS_SU_CNTL_FRONT_CW; 1116 1117 /* don't set A6XX_GRAS_SU_CNTL_LINEHALFWIDTH */ 1118 1119 if (rast_info->depthBiasEnable) 1120 gras_su_cntl |= A6XX_GRAS_SU_CNTL_POLY_OFFSET; 1121 1122 if (samples > VK_SAMPLE_COUNT_1_BIT) 1123 gras_su_cntl |= A6XX_GRAS_SU_CNTL_MSAA_ENABLE; 1124 1125 return gras_su_cntl; 1126} 1127 1128void 1129tu6_emit_gras_su_cntl(struct tu_cs *cs, 1130 uint32_t gras_su_cntl, 1131 float line_width) 1132{ 1133 assert((gras_su_cntl & A6XX_GRAS_SU_CNTL_LINEHALFWIDTH__MASK) == 0); 1134 gras_su_cntl |= A6XX_GRAS_SU_CNTL_LINEHALFWIDTH(line_width / 2.0f); 1135 1136 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_CNTL, 1); 1137 tu_cs_emit(cs, gras_su_cntl); 1138} 1139 1140void 1141tu6_emit_depth_bias(struct tu_cs *cs, 1142 float constant_factor, 1143 float clamp, 1144 float slope_factor) 1145{ 1146 tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_POLY_OFFSET_SCALE, 3); 1147 tu_cs_emit(cs, A6XX_GRAS_SU_POLY_OFFSET_SCALE(slope_factor)); 1148 tu_cs_emit(cs, A6XX_GRAS_SU_POLY_OFFSET_OFFSET(constant_factor)); 1149 tu_cs_emit(cs, A6XX_GRAS_SU_POLY_OFFSET_OFFSET_CLAMP(clamp)); 1150} 1151 1152static void 1153tu6_emit_alpha_control_disable(struct tu_cs *cs) 1154{ 1155 tu_cs_emit_pkt4(cs, REG_A6XX_RB_ALPHA_CONTROL, 1); 1156 tu_cs_emit(cs, 0); 1157} 1158 1159static void 1160tu6_emit_depth_control(struct tu_cs *cs, 1161 const VkPipelineDepthStencilStateCreateInfo *ds_info) 1162{ 1163 assert(!ds_info->depthBoundsTestEnable); 1164 1165 uint32_t rb_depth_cntl = 0; 1166 if (ds_info->depthTestEnable) { 1167 rb_depth_cntl |= 1168 A6XX_RB_DEPTH_CNTL_Z_ENABLE | 1169 A6XX_RB_DEPTH_CNTL_ZFUNC(tu6_compare_func(ds_info->depthCompareOp)) | 1170 A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE; 1171 1172 if (ds_info->depthWriteEnable) 1173 rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE; 1174 } 1175 1176 tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_CNTL, 1); 1177 tu_cs_emit(cs, rb_depth_cntl); 1178} 1179 1180static void 1181tu6_emit_stencil_control(struct tu_cs *cs, 1182 const VkPipelineDepthStencilStateCreateInfo *ds_info) 1183{ 1184 uint32_t rb_stencil_control = 0; 1185 if (ds_info->stencilTestEnable) { 1186 const VkStencilOpState *front = &ds_info->front; 1187 const VkStencilOpState *back = &ds_info->back; 1188 rb_stencil_control |= 1189 A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE | 1190 A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF | 1191 A6XX_RB_STENCIL_CONTROL_STENCIL_READ | 1192 A6XX_RB_STENCIL_CONTROL_FUNC(tu6_compare_func(front->compareOp)) | 1193 A6XX_RB_STENCIL_CONTROL_FAIL(tu6_stencil_op(front->failOp)) | 1194 A6XX_RB_STENCIL_CONTROL_ZPASS(tu6_stencil_op(front->passOp)) | 1195 A6XX_RB_STENCIL_CONTROL_ZFAIL(tu6_stencil_op(front->depthFailOp)) | 1196 A6XX_RB_STENCIL_CONTROL_FUNC_BF(tu6_compare_func(back->compareOp)) | 1197 A6XX_RB_STENCIL_CONTROL_FAIL_BF(tu6_stencil_op(back->failOp)) | 1198 A6XX_RB_STENCIL_CONTROL_ZPASS_BF(tu6_stencil_op(back->passOp)) | 1199 A6XX_RB_STENCIL_CONTROL_ZFAIL_BF(tu6_stencil_op(back->depthFailOp)); 1200 } 1201 1202 tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCIL_CONTROL, 1); 1203 tu_cs_emit(cs, rb_stencil_control); 1204} 1205 1206void 1207tu6_emit_stencil_compare_mask(struct tu_cs *cs, uint32_t front, uint32_t back) 1208{ 1209 tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCILMASK, 1); 1210 tu_cs_emit( 1211 cs, A6XX_RB_STENCILMASK_MASK(front) | A6XX_RB_STENCILMASK_BFMASK(back)); 1212} 1213 1214void 1215tu6_emit_stencil_write_mask(struct tu_cs *cs, uint32_t front, uint32_t back) 1216{ 1217 tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCILWRMASK, 1); 1218 tu_cs_emit(cs, A6XX_RB_STENCILWRMASK_WRMASK(front) | 1219 A6XX_RB_STENCILWRMASK_BFWRMASK(back)); 1220} 1221 1222void 1223tu6_emit_stencil_reference(struct tu_cs *cs, uint32_t front, uint32_t back) 1224{ 1225 tu_cs_emit_pkt4(cs, REG_A6XX_RB_STENCILREF, 1); 1226 tu_cs_emit(cs, 1227 A6XX_RB_STENCILREF_REF(front) | A6XX_RB_STENCILREF_BFREF(back)); 1228} 1229 1230static uint32_t 1231tu6_rb_mrt_blend_control(const VkPipelineColorBlendAttachmentState *att, 1232 bool has_alpha) 1233{ 1234 const enum a3xx_rb_blend_opcode color_op = tu6_blend_op(att->colorBlendOp); 1235 const enum adreno_rb_blend_factor src_color_factor = tu6_blend_factor( 1236 has_alpha ? att->srcColorBlendFactor 1237 : tu_blend_factor_no_dst_alpha(att->srcColorBlendFactor)); 1238 const enum adreno_rb_blend_factor dst_color_factor = tu6_blend_factor( 1239 has_alpha ? att->dstColorBlendFactor 1240 : tu_blend_factor_no_dst_alpha(att->dstColorBlendFactor)); 1241 const enum a3xx_rb_blend_opcode alpha_op = tu6_blend_op(att->alphaBlendOp); 1242 const enum adreno_rb_blend_factor src_alpha_factor = 1243 tu6_blend_factor(att->srcAlphaBlendFactor); 1244 const enum adreno_rb_blend_factor dst_alpha_factor = 1245 tu6_blend_factor(att->dstAlphaBlendFactor); 1246 1247 return A6XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(src_color_factor) | 1248 A6XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(color_op) | 1249 A6XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(dst_color_factor) | 1250 A6XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(src_alpha_factor) | 1251 A6XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(alpha_op) | 1252 A6XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(dst_alpha_factor); 1253} 1254 1255static uint32_t 1256tu6_rb_mrt_control(const VkPipelineColorBlendAttachmentState *att, 1257 uint32_t rb_mrt_control_rop, 1258 bool is_int, 1259 bool has_alpha) 1260{ 1261 uint32_t rb_mrt_control = 1262 A6XX_RB_MRT_CONTROL_COMPONENT_ENABLE(att->colorWriteMask); 1263 1264 /* ignore blending and logic op for integer attachments */ 1265 if (is_int) { 1266 rb_mrt_control |= A6XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY); 1267 return rb_mrt_control; 1268 } 1269 1270 rb_mrt_control |= rb_mrt_control_rop; 1271 1272 if (att->blendEnable) { 1273 rb_mrt_control |= A6XX_RB_MRT_CONTROL_BLEND; 1274 1275 if (has_alpha) 1276 rb_mrt_control |= A6XX_RB_MRT_CONTROL_BLEND2; 1277 } 1278 1279 return rb_mrt_control; 1280} 1281 1282static void 1283tu6_emit_rb_mrt_controls(struct tu_cs *cs, 1284 const VkPipelineColorBlendStateCreateInfo *blend_info, 1285 const VkFormat attachment_formats[MAX_RTS], 1286 uint32_t *blend_enable_mask) 1287{ 1288 *blend_enable_mask = 0; 1289 1290 bool rop_reads_dst = false; 1291 uint32_t rb_mrt_control_rop = 0; 1292 if (blend_info->logicOpEnable) { 1293 rop_reads_dst = tu_logic_op_reads_dst(blend_info->logicOp); 1294 rb_mrt_control_rop = 1295 A6XX_RB_MRT_CONTROL_ROP_ENABLE | 1296 A6XX_RB_MRT_CONTROL_ROP_CODE(tu6_rop(blend_info->logicOp)); 1297 } 1298 1299 for (uint32_t i = 0; i < blend_info->attachmentCount; i++) { 1300 const VkPipelineColorBlendAttachmentState *att = 1301 &blend_info->pAttachments[i]; 1302 const VkFormat format = attachment_formats[i]; 1303 1304 uint32_t rb_mrt_control = 0; 1305 uint32_t rb_mrt_blend_control = 0; 1306 if (format != VK_FORMAT_UNDEFINED) { 1307 const bool is_int = vk_format_is_int(format); 1308 const bool has_alpha = vk_format_has_alpha(format); 1309 1310 rb_mrt_control = 1311 tu6_rb_mrt_control(att, rb_mrt_control_rop, is_int, has_alpha); 1312 rb_mrt_blend_control = tu6_rb_mrt_blend_control(att, has_alpha); 1313 1314 if (att->blendEnable || rop_reads_dst) 1315 *blend_enable_mask |= 1 << i; 1316 } 1317 1318 tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_CONTROL(i), 2); 1319 tu_cs_emit(cs, rb_mrt_control); 1320 tu_cs_emit(cs, rb_mrt_blend_control); 1321 } 1322 1323 for (uint32_t i = blend_info->attachmentCount; i < MAX_RTS; i++) { 1324 tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_CONTROL(i), 2); 1325 tu_cs_emit(cs, 0); 1326 tu_cs_emit(cs, 0); 1327 } 1328} 1329 1330static void 1331tu6_emit_blend_control(struct tu_cs *cs, 1332 uint32_t blend_enable_mask, 1333 const VkPipelineMultisampleStateCreateInfo *msaa_info) 1334{ 1335 assert(!msaa_info->sampleShadingEnable); 1336 assert(!msaa_info->alphaToOneEnable); 1337 1338 uint32_t sp_blend_cntl = A6XX_SP_BLEND_CNTL_UNK8; 1339 if (blend_enable_mask) 1340 sp_blend_cntl |= A6XX_SP_BLEND_CNTL_ENABLED; 1341 if (msaa_info->alphaToCoverageEnable) 1342 sp_blend_cntl |= A6XX_SP_BLEND_CNTL_ALPHA_TO_COVERAGE; 1343 1344 const uint32_t sample_mask = 1345 msaa_info->pSampleMask ? *msaa_info->pSampleMask 1346 : ((1 << msaa_info->rasterizationSamples) - 1); 1347 1348 /* set A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND only when enabled? */ 1349 uint32_t rb_blend_cntl = 1350 A6XX_RB_BLEND_CNTL_ENABLE_BLEND(blend_enable_mask) | 1351 A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND | 1352 A6XX_RB_BLEND_CNTL_SAMPLE_MASK(sample_mask); 1353 if (msaa_info->alphaToCoverageEnable) 1354 rb_blend_cntl |= A6XX_RB_BLEND_CNTL_ALPHA_TO_COVERAGE; 1355 1356 tu_cs_emit_pkt4(cs, REG_A6XX_SP_BLEND_CNTL, 1); 1357 tu_cs_emit(cs, sp_blend_cntl); 1358 1359 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLEND_CNTL, 1); 1360 tu_cs_emit(cs, rb_blend_cntl); 1361} 1362 1363void 1364tu6_emit_blend_constants(struct tu_cs *cs, const float constants[4]) 1365{ 1366 tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLEND_RED_F32, 4); 1367 tu_cs_emit_array(cs, (const uint32_t *) constants, 4); 1368} 1369 1370static VkResult 1371tu_pipeline_builder_create_pipeline(struct tu_pipeline_builder *builder, 1372 struct tu_pipeline **out_pipeline) 1373{ 1374 struct tu_device *dev = builder->device; 1375 1376 struct tu_pipeline *pipeline = 1377 vk_zalloc2(&dev->alloc, builder->alloc, sizeof(*pipeline), 8, 1378 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1379 if (!pipeline) 1380 return VK_ERROR_OUT_OF_HOST_MEMORY; 1381 1382 tu_cs_init(&pipeline->cs, TU_CS_MODE_SUB_STREAM, 2048); 1383 1384 /* reserve the space now such that tu_cs_begin_sub_stream never fails */ 1385 VkResult result = tu_cs_reserve_space(dev, &pipeline->cs, 2048); 1386 if (result != VK_SUCCESS) { 1387 vk_free2(&dev->alloc, builder->alloc, pipeline); 1388 return result; 1389 } 1390 1391 *out_pipeline = pipeline; 1392 1393 return VK_SUCCESS; 1394} 1395 1396static VkResult 1397tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder) 1398{ 1399 const VkPipelineShaderStageCreateInfo *stage_infos[MESA_SHADER_STAGES] = { 1400 NULL 1401 }; 1402 for (uint32_t i = 0; i < builder->create_info->stageCount; i++) { 1403 gl_shader_stage stage = 1404 tu_shader_stage(builder->create_info->pStages[i].stage); 1405 stage_infos[stage] = &builder->create_info->pStages[i]; 1406 } 1407 1408 struct tu_shader_compile_options options; 1409 tu_shader_compile_options_init(&options, builder->create_info); 1410 1411 /* compile shaders in reverse order */ 1412 struct tu_shader *next_stage_shader = NULL; 1413 for (gl_shader_stage stage = MESA_SHADER_STAGES - 1; 1414 stage > MESA_SHADER_NONE; stage--) { 1415 const VkPipelineShaderStageCreateInfo *stage_info = stage_infos[stage]; 1416 if (!stage_info) 1417 continue; 1418 1419 struct tu_shader *shader = 1420 tu_shader_create(builder->device, stage, stage_info, builder->alloc); 1421 if (!shader) 1422 return VK_ERROR_OUT_OF_HOST_MEMORY; 1423 1424 VkResult result = 1425 tu_shader_compile(builder->device, shader, next_stage_shader, 1426 &options, builder->alloc); 1427 if (result != VK_SUCCESS) 1428 return result; 1429 1430 builder->shaders[stage] = shader; 1431 builder->shader_offsets[stage] = builder->shader_total_size; 1432 builder->shader_total_size += 1433 sizeof(uint32_t) * shader->variants[0].info.sizedwords; 1434 1435 next_stage_shader = shader; 1436 } 1437 1438 if (builder->shaders[MESA_SHADER_VERTEX]->has_binning_pass) { 1439 const struct tu_shader *vs = builder->shaders[MESA_SHADER_VERTEX]; 1440 builder->binning_vs_offset = builder->shader_total_size; 1441 builder->shader_total_size += 1442 sizeof(uint32_t) * vs->variants[1].info.sizedwords; 1443 } 1444 1445 return VK_SUCCESS; 1446} 1447 1448static VkResult 1449tu_pipeline_builder_upload_shaders(struct tu_pipeline_builder *builder, 1450 struct tu_pipeline *pipeline) 1451{ 1452 struct tu_bo *bo = &pipeline->program.binary_bo; 1453 1454 VkResult result = 1455 tu_bo_init_new(builder->device, bo, builder->shader_total_size); 1456 if (result != VK_SUCCESS) 1457 return result; 1458 1459 result = tu_bo_map(builder->device, bo); 1460 if (result != VK_SUCCESS) 1461 return result; 1462 1463 for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { 1464 const struct tu_shader *shader = builder->shaders[i]; 1465 if (!shader) 1466 continue; 1467 1468 memcpy(bo->map + builder->shader_offsets[i], shader->binary, 1469 sizeof(uint32_t) * shader->variants[0].info.sizedwords); 1470 } 1471 1472 if (builder->shaders[MESA_SHADER_VERTEX]->has_binning_pass) { 1473 const struct tu_shader *vs = builder->shaders[MESA_SHADER_VERTEX]; 1474 memcpy(bo->map + builder->binning_vs_offset, vs->binning_binary, 1475 sizeof(uint32_t) * vs->variants[1].info.sizedwords); 1476 } 1477 1478 return VK_SUCCESS; 1479} 1480 1481static void 1482tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, 1483 struct tu_pipeline *pipeline) 1484{ 1485 const VkPipelineDynamicStateCreateInfo *dynamic_info = 1486 builder->create_info->pDynamicState; 1487 1488 if (!dynamic_info) 1489 return; 1490 1491 for (uint32_t i = 0; i < dynamic_info->dynamicStateCount; i++) { 1492 pipeline->dynamic_state.mask |= 1493 tu_dynamic_state_bit(dynamic_info->pDynamicStates[i]); 1494 } 1495} 1496 1497static void 1498tu_pipeline_builder_parse_shader_stages(struct tu_pipeline_builder *builder, 1499 struct tu_pipeline *pipeline) 1500{ 1501 struct tu_cs prog_cs; 1502 tu_cs_begin_sub_stream(builder->device, &pipeline->cs, 512, &prog_cs); 1503 tu6_emit_program(&prog_cs, builder, &pipeline->program.binary_bo, false); 1504 pipeline->program.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &prog_cs); 1505 1506 tu_cs_begin_sub_stream(builder->device, &pipeline->cs, 512, &prog_cs); 1507 tu6_emit_program(&prog_cs, builder, &pipeline->program.binary_bo, true); 1508 pipeline->program.binning_state_ib = 1509 tu_cs_end_sub_stream(&pipeline->cs, &prog_cs); 1510} 1511 1512static void 1513tu_pipeline_builder_parse_vertex_input(struct tu_pipeline_builder *builder, 1514 struct tu_pipeline *pipeline) 1515{ 1516 const VkPipelineVertexInputStateCreateInfo *vi_info = 1517 builder->create_info->pVertexInputState; 1518 const struct tu_shader *vs = builder->shaders[MESA_SHADER_VERTEX]; 1519 1520 struct tu_cs vi_cs; 1521 tu_cs_begin_sub_stream(builder->device, &pipeline->cs, 1522 MAX_VERTEX_ATTRIBS * 5 + 2, &vi_cs); 1523 tu6_emit_vertex_input(&vi_cs, &vs->variants[0], vi_info, 1524 pipeline->vi.bindings, pipeline->vi.strides, 1525 pipeline->vi.offsets, &pipeline->vi.count); 1526 pipeline->vi.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &vi_cs); 1527 1528 if (vs->has_binning_pass) { 1529 tu_cs_begin_sub_stream(builder->device, &pipeline->cs, 1530 MAX_VERTEX_ATTRIBS * 5 + 2, &vi_cs); 1531 tu6_emit_vertex_input( 1532 &vi_cs, &vs->variants[1], vi_info, pipeline->vi.binning_bindings, 1533 pipeline->vi.binning_strides, pipeline->vi.binning_offsets, 1534 &pipeline->vi.binning_count); 1535 pipeline->vi.binning_state_ib = 1536 tu_cs_end_sub_stream(&pipeline->cs, &vi_cs); 1537 } 1538} 1539 1540static void 1541tu_pipeline_builder_parse_input_assembly(struct tu_pipeline_builder *builder, 1542 struct tu_pipeline *pipeline) 1543{ 1544 const VkPipelineInputAssemblyStateCreateInfo *ia_info = 1545 builder->create_info->pInputAssemblyState; 1546 1547 pipeline->ia.primtype = tu6_primtype(ia_info->topology); 1548 pipeline->ia.primitive_restart = ia_info->primitiveRestartEnable; 1549} 1550 1551static void 1552tu_pipeline_builder_parse_viewport(struct tu_pipeline_builder *builder, 1553 struct tu_pipeline *pipeline) 1554{ 1555 /* The spec says: 1556 * 1557 * pViewportState is a pointer to an instance of the 1558 * VkPipelineViewportStateCreateInfo structure, and is ignored if the 1559 * pipeline has rasterization disabled." 1560 * 1561 * We leave the relevant registers stale in that case. 1562 */ 1563 if (builder->rasterizer_discard) 1564 return; 1565 1566 const VkPipelineViewportStateCreateInfo *vp_info = 1567 builder->create_info->pViewportState; 1568 1569 struct tu_cs vp_cs; 1570 tu_cs_begin_sub_stream(builder->device, &pipeline->cs, 15, &vp_cs); 1571 1572 if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_VIEWPORT)) { 1573 assert(vp_info->viewportCount == 1); 1574 tu6_emit_viewport(&vp_cs, vp_info->pViewports); 1575 } 1576 1577 if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_SCISSOR)) { 1578 assert(vp_info->scissorCount == 1); 1579 tu6_emit_scissor(&vp_cs, vp_info->pScissors); 1580 } 1581 1582 pipeline->vp.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &vp_cs); 1583} 1584 1585static void 1586tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder, 1587 struct tu_pipeline *pipeline) 1588{ 1589 const VkPipelineRasterizationStateCreateInfo *rast_info = 1590 builder->create_info->pRasterizationState; 1591 1592 assert(!rast_info->depthClampEnable); 1593 assert(rast_info->polygonMode == VK_POLYGON_MODE_FILL); 1594 1595 struct tu_cs rast_cs; 1596 tu_cs_begin_sub_stream(builder->device, &pipeline->cs, 20, &rast_cs); 1597 1598 /* move to hw ctx init? */ 1599 tu6_emit_gras_unknowns(&rast_cs); 1600 tu6_emit_point_size(&rast_cs); 1601 1602 const uint32_t gras_su_cntl = 1603 tu6_gras_su_cntl(rast_info, builder->samples); 1604 1605 if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_LINE_WIDTH)) 1606 tu6_emit_gras_su_cntl(&rast_cs, gras_su_cntl, rast_info->lineWidth); 1607 1608 if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_DEPTH_BIAS)) { 1609 tu6_emit_depth_bias(&rast_cs, rast_info->depthBiasConstantFactor, 1610 rast_info->depthBiasClamp, 1611 rast_info->depthBiasSlopeFactor); 1612 } 1613 1614 pipeline->rast.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &rast_cs); 1615 1616 pipeline->rast.gras_su_cntl = gras_su_cntl; 1617} 1618 1619static void 1620tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder, 1621 struct tu_pipeline *pipeline) 1622{ 1623 /* The spec says: 1624 * 1625 * pDepthStencilState is a pointer to an instance of the 1626 * VkPipelineDepthStencilStateCreateInfo structure, and is ignored if 1627 * the pipeline has rasterization disabled or if the subpass of the 1628 * render pass the pipeline is created against does not use a 1629 * depth/stencil attachment. 1630 * 1631 * We disable both depth and stenil tests in those cases. 1632 */ 1633 static const VkPipelineDepthStencilStateCreateInfo dummy_ds_info; 1634 const VkPipelineDepthStencilStateCreateInfo *ds_info = 1635 builder->use_depth_stencil_attachment 1636 ? builder->create_info->pDepthStencilState 1637 : &dummy_ds_info; 1638 1639 struct tu_cs ds_cs; 1640 tu_cs_begin_sub_stream(builder->device, &pipeline->cs, 12, &ds_cs); 1641 1642 /* move to hw ctx init? */ 1643 tu6_emit_alpha_control_disable(&ds_cs); 1644 1645 tu6_emit_depth_control(&ds_cs, ds_info); 1646 tu6_emit_stencil_control(&ds_cs, ds_info); 1647 1648 if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_STENCIL_COMPARE_MASK)) { 1649 tu6_emit_stencil_compare_mask(&ds_cs, ds_info->front.compareMask, 1650 ds_info->back.compareMask); 1651 } 1652 if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_STENCIL_WRITE_MASK)) { 1653 tu6_emit_stencil_write_mask(&ds_cs, ds_info->front.writeMask, 1654 ds_info->back.writeMask); 1655 } 1656 if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_STENCIL_REFERENCE)) { 1657 tu6_emit_stencil_reference(&ds_cs, ds_info->front.reference, 1658 ds_info->back.reference); 1659 } 1660 1661 pipeline->ds.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &ds_cs); 1662} 1663 1664static void 1665tu_pipeline_builder_parse_multisample_and_color_blend( 1666 struct tu_pipeline_builder *builder, struct tu_pipeline *pipeline) 1667{ 1668 /* The spec says: 1669 * 1670 * pMultisampleState is a pointer to an instance of the 1671 * VkPipelineMultisampleStateCreateInfo, and is ignored if the pipeline 1672 * has rasterization disabled. 1673 * 1674 * Also, 1675 * 1676 * pColorBlendState is a pointer to an instance of the 1677 * VkPipelineColorBlendStateCreateInfo structure, and is ignored if the 1678 * pipeline has rasterization disabled or if the subpass of the render 1679 * pass the pipeline is created against does not use any color 1680 * attachments. 1681 * 1682 * We leave the relevant registers stale when rasterization is disabled. 1683 */ 1684 if (builder->rasterizer_discard) 1685 return; 1686 1687 static const VkPipelineColorBlendStateCreateInfo dummy_blend_info; 1688 const VkPipelineMultisampleStateCreateInfo *msaa_info = 1689 builder->create_info->pMultisampleState; 1690 const VkPipelineColorBlendStateCreateInfo *blend_info = 1691 builder->use_color_attachments ? builder->create_info->pColorBlendState 1692 : &dummy_blend_info; 1693 1694 struct tu_cs blend_cs; 1695 tu_cs_begin_sub_stream(builder->device, &pipeline->cs, MAX_RTS * 3 + 9, 1696 &blend_cs); 1697 1698 uint32_t blend_enable_mask; 1699 tu6_emit_rb_mrt_controls(&blend_cs, blend_info, 1700 builder->color_attachment_formats, 1701 &blend_enable_mask); 1702 1703 if (!(pipeline->dynamic_state.mask & TU_DYNAMIC_BLEND_CONSTANTS)) 1704 tu6_emit_blend_constants(&blend_cs, blend_info->blendConstants); 1705 1706 tu6_emit_blend_control(&blend_cs, blend_enable_mask, msaa_info); 1707 1708 pipeline->blend.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &blend_cs); 1709} 1710 1711static void 1712tu_pipeline_finish(struct tu_pipeline *pipeline, 1713 struct tu_device *dev, 1714 const VkAllocationCallbacks *alloc) 1715{ 1716 tu_cs_finish(dev, &pipeline->cs); 1717 1718 if (pipeline->program.binary_bo.gem_handle) 1719 tu_bo_finish(dev, &pipeline->program.binary_bo); 1720} 1721 1722static VkResult 1723tu_pipeline_builder_build(struct tu_pipeline_builder *builder, 1724 struct tu_pipeline **pipeline) 1725{ 1726 VkResult result = tu_pipeline_builder_create_pipeline(builder, pipeline); 1727 if (result != VK_SUCCESS) 1728 return result; 1729 1730 /* compile and upload shaders */ 1731 result = tu_pipeline_builder_compile_shaders(builder); 1732 if (result == VK_SUCCESS) 1733 result = tu_pipeline_builder_upload_shaders(builder, *pipeline); 1734 if (result != VK_SUCCESS) { 1735 tu_pipeline_finish(*pipeline, builder->device, builder->alloc); 1736 vk_free2(&builder->device->alloc, builder->alloc, *pipeline); 1737 *pipeline = VK_NULL_HANDLE; 1738 1739 return result; 1740 } 1741 1742 tu_pipeline_builder_parse_dynamic(builder, *pipeline); 1743 tu_pipeline_builder_parse_shader_stages(builder, *pipeline); 1744 tu_pipeline_builder_parse_vertex_input(builder, *pipeline); 1745 tu_pipeline_builder_parse_input_assembly(builder, *pipeline); 1746 tu_pipeline_builder_parse_viewport(builder, *pipeline); 1747 tu_pipeline_builder_parse_rasterization(builder, *pipeline); 1748 tu_pipeline_builder_parse_depth_stencil(builder, *pipeline); 1749 tu_pipeline_builder_parse_multisample_and_color_blend(builder, *pipeline); 1750 1751 /* we should have reserved enough space upfront such that the CS never 1752 * grows 1753 */ 1754 assert((*pipeline)->cs.bo_count == 1); 1755 1756 return VK_SUCCESS; 1757} 1758 1759static void 1760tu_pipeline_builder_finish(struct tu_pipeline_builder *builder) 1761{ 1762 for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { 1763 if (!builder->shaders[i]) 1764 continue; 1765 tu_shader_destroy(builder->device, builder->shaders[i], builder->alloc); 1766 } 1767} 1768 1769static void 1770tu_pipeline_builder_init_graphics( 1771 struct tu_pipeline_builder *builder, 1772 struct tu_device *dev, 1773 struct tu_pipeline_cache *cache, 1774 const VkGraphicsPipelineCreateInfo *create_info, 1775 const VkAllocationCallbacks *alloc) 1776{ 1777 *builder = (struct tu_pipeline_builder) { 1778 .device = dev, 1779 .cache = cache, 1780 .create_info = create_info, 1781 .alloc = alloc, 1782 }; 1783 1784 builder->rasterizer_discard = 1785 create_info->pRasterizationState->rasterizerDiscardEnable; 1786 1787 if (builder->rasterizer_discard) { 1788 builder->samples = VK_SAMPLE_COUNT_1_BIT; 1789 } else { 1790 builder->samples = create_info->pMultisampleState->rasterizationSamples; 1791 1792 const struct tu_render_pass *pass = 1793 tu_render_pass_from_handle(create_info->renderPass); 1794 const struct tu_subpass *subpass = 1795 &pass->subpasses[create_info->subpass]; 1796 1797 builder->use_depth_stencil_attachment = 1798 subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED; 1799 1800 assert(subpass->color_count == 1801 create_info->pColorBlendState->attachmentCount); 1802 builder->color_attachment_count = subpass->color_count; 1803 for (uint32_t i = 0; i < subpass->color_count; i++) { 1804 const uint32_t a = subpass->color_attachments[i].attachment; 1805 if (a == VK_ATTACHMENT_UNUSED) 1806 continue; 1807 1808 builder->color_attachment_formats[i] = pass->attachments[a].format; 1809 builder->use_color_attachments = true; 1810 } 1811 } 1812} 1813 1814VkResult 1815tu_CreateGraphicsPipelines(VkDevice device, 1816 VkPipelineCache pipelineCache, 1817 uint32_t count, 1818 const VkGraphicsPipelineCreateInfo *pCreateInfos, 1819 const VkAllocationCallbacks *pAllocator, 1820 VkPipeline *pPipelines) 1821{ 1822 TU_FROM_HANDLE(tu_device, dev, device); 1823 TU_FROM_HANDLE(tu_pipeline_cache, cache, pipelineCache); 1824 1825 for (uint32_t i = 0; i < count; i++) { 1826 struct tu_pipeline_builder builder; 1827 tu_pipeline_builder_init_graphics(&builder, dev, cache, 1828 &pCreateInfos[i], pAllocator); 1829 1830 struct tu_pipeline *pipeline; 1831 VkResult result = tu_pipeline_builder_build(&builder, &pipeline); 1832 tu_pipeline_builder_finish(&builder); 1833 1834 if (result != VK_SUCCESS) { 1835 for (uint32_t j = 0; j < i; j++) { 1836 tu_DestroyPipeline(device, pPipelines[j], pAllocator); 1837 pPipelines[j] = VK_NULL_HANDLE; 1838 } 1839 1840 return result; 1841 } 1842 1843 pPipelines[i] = tu_pipeline_to_handle(pipeline); 1844 } 1845 1846 return VK_SUCCESS; 1847} 1848 1849static VkResult 1850tu_compute_pipeline_create(VkDevice _device, 1851 VkPipelineCache _cache, 1852 const VkComputePipelineCreateInfo *pCreateInfo, 1853 const VkAllocationCallbacks *pAllocator, 1854 VkPipeline *pPipeline) 1855{ 1856 return VK_SUCCESS; 1857} 1858 1859VkResult 1860tu_CreateComputePipelines(VkDevice _device, 1861 VkPipelineCache pipelineCache, 1862 uint32_t count, 1863 const VkComputePipelineCreateInfo *pCreateInfos, 1864 const VkAllocationCallbacks *pAllocator, 1865 VkPipeline *pPipelines) 1866{ 1867 VkResult result = VK_SUCCESS; 1868 1869 unsigned i = 0; 1870 for (; i < count; i++) { 1871 VkResult r; 1872 r = tu_compute_pipeline_create(_device, pipelineCache, &pCreateInfos[i], 1873 pAllocator, &pPipelines[i]); 1874 if (r != VK_SUCCESS) { 1875 result = r; 1876 pPipelines[i] = VK_NULL_HANDLE; 1877 } 1878 } 1879 1880 return result; 1881} 1882 1883void 1884tu_DestroyPipeline(VkDevice _device, 1885 VkPipeline _pipeline, 1886 const VkAllocationCallbacks *pAllocator) 1887{ 1888 TU_FROM_HANDLE(tu_device, dev, _device); 1889 TU_FROM_HANDLE(tu_pipeline, pipeline, _pipeline); 1890 1891 if (!_pipeline) 1892 return; 1893 1894 tu_pipeline_finish(pipeline, dev, pAllocator); 1895 vk_free2(&dev->alloc, pAllocator, pipeline); 1896} 1897