1/* 2 * Copyright © 2021 Raspberry Pi 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 "v3dv_private.h" 25#include "broadcom/common/v3d_macros.h" 26#include "broadcom/cle/v3dx_pack.h" 27#include "broadcom/compiler/v3d_compiler.h" 28 29#include "vk_format_info.h" 30 31static uint8_t 32blend_factor(VkBlendFactor factor, bool dst_alpha_one, bool *needs_constants) 33{ 34 switch (factor) { 35 case VK_BLEND_FACTOR_ZERO: 36 case VK_BLEND_FACTOR_ONE: 37 case VK_BLEND_FACTOR_SRC_COLOR: 38 case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: 39 case VK_BLEND_FACTOR_DST_COLOR: 40 case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: 41 case VK_BLEND_FACTOR_SRC_ALPHA: 42 case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: 43 case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: 44 return factor; 45 case VK_BLEND_FACTOR_CONSTANT_COLOR: 46 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: 47 case VK_BLEND_FACTOR_CONSTANT_ALPHA: 48 case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: 49 *needs_constants = true; 50 return factor; 51 case VK_BLEND_FACTOR_DST_ALPHA: 52 return dst_alpha_one ? V3D_BLEND_FACTOR_ONE : 53 V3D_BLEND_FACTOR_DST_ALPHA; 54 case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: 55 return dst_alpha_one ? V3D_BLEND_FACTOR_ZERO : 56 V3D_BLEND_FACTOR_INV_DST_ALPHA; 57 case VK_BLEND_FACTOR_SRC1_COLOR: 58 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: 59 case VK_BLEND_FACTOR_SRC1_ALPHA: 60 case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: 61 assert(!"Invalid blend factor: dual source blending not supported."); 62 default: 63 assert(!"Unknown blend factor."); 64 } 65 66 /* Should be handled by the switch, added to avoid a "end of non-void 67 * function" error 68 */ 69 unreachable("Unknown blend factor."); 70} 71 72static void 73pack_blend(struct v3dv_pipeline *pipeline, 74 const VkPipelineColorBlendStateCreateInfo *cb_info) 75{ 76 /* By default, we are not enabling blending and all color channel writes are 77 * enabled. Color write enables are independent of whether blending is 78 * enabled or not. 79 * 80 * Vulkan specifies color write masks so that bits set correspond to 81 * enabled channels. Our hardware does it the other way around. 82 */ 83 pipeline->blend.enables = 0; 84 pipeline->blend.color_write_masks = 0; /* All channels enabled */ 85 86 if (!cb_info) 87 return; 88 89 assert(pipeline->subpass); 90 if (pipeline->subpass->color_count == 0) 91 return; 92 93 assert(pipeline->subpass->color_count == cb_info->attachmentCount); 94 95 pipeline->blend.needs_color_constants = false; 96 uint32_t color_write_masks = 0; 97 for (uint32_t i = 0; i < pipeline->subpass->color_count; i++) { 98 const VkPipelineColorBlendAttachmentState *b_state = 99 &cb_info->pAttachments[i]; 100 101 uint32_t attachment_idx = 102 pipeline->subpass->color_attachments[i].attachment; 103 if (attachment_idx == VK_ATTACHMENT_UNUSED) 104 continue; 105 106 color_write_masks |= (~b_state->colorWriteMask & 0xf) << (4 * i); 107 108 if (!b_state->blendEnable) 109 continue; 110 111 VkAttachmentDescription *desc = 112 &pipeline->pass->attachments[attachment_idx].desc; 113 const struct v3dv_format *format = v3dX(get_format)(desc->format); 114 bool dst_alpha_one = (format->swizzle[3] == PIPE_SWIZZLE_1); 115 116 uint8_t rt_mask = 1 << i; 117 pipeline->blend.enables |= rt_mask; 118 119 v3dvx_pack(pipeline->blend.cfg[i], BLEND_CFG, config) { 120 config.render_target_mask = rt_mask; 121 122 config.color_blend_mode = b_state->colorBlendOp; 123 config.color_blend_dst_factor = 124 blend_factor(b_state->dstColorBlendFactor, dst_alpha_one, 125 &pipeline->blend.needs_color_constants); 126 config.color_blend_src_factor = 127 blend_factor(b_state->srcColorBlendFactor, dst_alpha_one, 128 &pipeline->blend.needs_color_constants); 129 130 config.alpha_blend_mode = b_state->alphaBlendOp; 131 config.alpha_blend_dst_factor = 132 blend_factor(b_state->dstAlphaBlendFactor, dst_alpha_one, 133 &pipeline->blend.needs_color_constants); 134 config.alpha_blend_src_factor = 135 blend_factor(b_state->srcAlphaBlendFactor, dst_alpha_one, 136 &pipeline->blend.needs_color_constants); 137 } 138 } 139 140 pipeline->blend.color_write_masks = color_write_masks; 141} 142 143/* This requires that pack_blend() had been called before so we can set 144 * the overall blend enable bit in the CFG_BITS packet. 145 */ 146static void 147pack_cfg_bits(struct v3dv_pipeline *pipeline, 148 const VkPipelineDepthStencilStateCreateInfo *ds_info, 149 const VkPipelineRasterizationStateCreateInfo *rs_info, 150 const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info, 151 const VkPipelineMultisampleStateCreateInfo *ms_info) 152{ 153 assert(sizeof(pipeline->cfg_bits) == cl_packet_length(CFG_BITS)); 154 155 pipeline->msaa = 156 ms_info && ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT; 157 158 v3dvx_pack(pipeline->cfg_bits, CFG_BITS, config) { 159 config.enable_forward_facing_primitive = 160 rs_info ? !(rs_info->cullMode & VK_CULL_MODE_FRONT_BIT) : false; 161 162 config.enable_reverse_facing_primitive = 163 rs_info ? !(rs_info->cullMode & VK_CULL_MODE_BACK_BIT) : false; 164 165 /* Seems like the hardware is backwards regarding this setting... */ 166 config.clockwise_primitives = 167 rs_info ? rs_info->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE : false; 168 169 config.enable_depth_offset = rs_info ? rs_info->depthBiasEnable: false; 170 171 /* This is required to pass line rasterization tests in CTS while 172 * exposing, at least, a minimum of 4-bits of subpixel precision 173 * (the minimum requirement). 174 */ 175 config.line_rasterization = 1; /* perp end caps */ 176 177 if (rs_info && rs_info->polygonMode != VK_POLYGON_MODE_FILL) { 178 config.direct3d_wireframe_triangles_mode = true; 179 config.direct3d_point_fill_mode = 180 rs_info->polygonMode == VK_POLYGON_MODE_POINT; 181 } 182 183 config.rasterizer_oversample_mode = pipeline->msaa ? 1 : 0; 184 185 /* From the Vulkan spec: 186 * 187 * "Provoking Vertex: 188 * 189 * The vertex in a primitive from which flat shaded attribute 190 * values are taken. This is generally the “first” vertex in the 191 * primitive, and depends on the primitive topology." 192 * 193 * First vertex is the Direct3D style for provoking vertex. OpenGL uses 194 * the last vertex by default. 195 */ 196 if (pv_info) { 197 config.direct3d_provoking_vertex = 198 pv_info->provokingVertexMode == 199 VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT; 200 } else { 201 config.direct3d_provoking_vertex = true; 202 } 203 204 config.blend_enable = pipeline->blend.enables != 0; 205 206 /* Disable depth/stencil if we don't have a D/S attachment */ 207 bool has_ds_attachment = 208 pipeline->subpass->ds_attachment.attachment != VK_ATTACHMENT_UNUSED; 209 210 if (ds_info && ds_info->depthTestEnable && has_ds_attachment) { 211 config.z_updates_enable = ds_info->depthWriteEnable; 212 config.depth_test_function = ds_info->depthCompareOp; 213 } else { 214 config.depth_test_function = VK_COMPARE_OP_ALWAYS; 215 } 216 217 /* EZ state will be updated at draw time based on bound pipeline state */ 218 config.early_z_updates_enable = false; 219 config.early_z_enable = false; 220 221 config.stencil_enable = 222 ds_info ? ds_info->stencilTestEnable && has_ds_attachment: false; 223 224 pipeline->z_updates_enable = config.z_updates_enable; 225 }; 226} 227 228static uint32_t 229translate_stencil_op(enum pipe_stencil_op op) 230{ 231 switch (op) { 232 case VK_STENCIL_OP_KEEP: 233 return V3D_STENCIL_OP_KEEP; 234 case VK_STENCIL_OP_ZERO: 235 return V3D_STENCIL_OP_ZERO; 236 case VK_STENCIL_OP_REPLACE: 237 return V3D_STENCIL_OP_REPLACE; 238 case VK_STENCIL_OP_INCREMENT_AND_CLAMP: 239 return V3D_STENCIL_OP_INCR; 240 case VK_STENCIL_OP_DECREMENT_AND_CLAMP: 241 return V3D_STENCIL_OP_DECR; 242 case VK_STENCIL_OP_INVERT: 243 return V3D_STENCIL_OP_INVERT; 244 case VK_STENCIL_OP_INCREMENT_AND_WRAP: 245 return V3D_STENCIL_OP_INCWRAP; 246 case VK_STENCIL_OP_DECREMENT_AND_WRAP: 247 return V3D_STENCIL_OP_DECWRAP; 248 default: 249 unreachable("bad stencil op"); 250 } 251} 252 253static void 254pack_single_stencil_cfg(struct v3dv_pipeline *pipeline, 255 uint8_t *stencil_cfg, 256 bool is_front, 257 bool is_back, 258 const VkStencilOpState *stencil_state) 259{ 260 /* From the Vulkan spec: 261 * 262 * "Reference is an integer reference value that is used in the unsigned 263 * stencil comparison. The reference value used by stencil comparison 264 * must be within the range [0,2^s-1] , where s is the number of bits in 265 * the stencil framebuffer attachment, otherwise the reference value is 266 * considered undefined." 267 * 268 * In our case, 's' is always 8, so we clamp to that to prevent our packing 269 * functions to assert in debug mode if they see larger values. 270 * 271 * If we have dynamic state we need to make sure we set the corresponding 272 * state bits to 0, since cl_emit_with_prepacked ORs the new value with 273 * the old. 274 */ 275 const uint8_t write_mask = 276 pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_WRITE_MASK ? 277 0 : stencil_state->writeMask & 0xff; 278 279 const uint8_t compare_mask = 280 pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_COMPARE_MASK ? 281 0 : stencil_state->compareMask & 0xff; 282 283 const uint8_t reference = 284 pipeline->dynamic_state.mask & V3DV_DYNAMIC_STENCIL_COMPARE_MASK ? 285 0 : stencil_state->reference & 0xff; 286 287 v3dvx_pack(stencil_cfg, STENCIL_CFG, config) { 288 config.front_config = is_front; 289 config.back_config = is_back; 290 config.stencil_write_mask = write_mask; 291 config.stencil_test_mask = compare_mask; 292 config.stencil_test_function = stencil_state->compareOp; 293 config.stencil_pass_op = translate_stencil_op(stencil_state->passOp); 294 config.depth_test_fail_op = translate_stencil_op(stencil_state->depthFailOp); 295 config.stencil_test_fail_op = translate_stencil_op(stencil_state->failOp); 296 config.stencil_ref_value = reference; 297 } 298} 299 300static void 301pack_stencil_cfg(struct v3dv_pipeline *pipeline, 302 const VkPipelineDepthStencilStateCreateInfo *ds_info) 303{ 304 assert(sizeof(pipeline->stencil_cfg) == 2 * cl_packet_length(STENCIL_CFG)); 305 306 if (!ds_info || !ds_info->stencilTestEnable) 307 return; 308 309 if (pipeline->subpass->ds_attachment.attachment == VK_ATTACHMENT_UNUSED) 310 return; 311 312 const uint32_t dynamic_stencil_states = V3DV_DYNAMIC_STENCIL_COMPARE_MASK | 313 V3DV_DYNAMIC_STENCIL_WRITE_MASK | 314 V3DV_DYNAMIC_STENCIL_REFERENCE; 315 316 317 /* If front != back or we have dynamic stencil state we can't emit a single 318 * packet for both faces. 319 */ 320 bool needs_front_and_back = false; 321 if ((pipeline->dynamic_state.mask & dynamic_stencil_states) || 322 memcmp(&ds_info->front, &ds_info->back, sizeof(ds_info->front))) 323 needs_front_and_back = true; 324 325 /* If the front and back configurations are the same we can emit both with 326 * a single packet. 327 */ 328 pipeline->emit_stencil_cfg[0] = true; 329 if (!needs_front_and_back) { 330 pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0], 331 true, true, &ds_info->front); 332 } else { 333 pipeline->emit_stencil_cfg[1] = true; 334 pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[0], 335 true, false, &ds_info->front); 336 pack_single_stencil_cfg(pipeline, pipeline->stencil_cfg[1], 337 false, true, &ds_info->back); 338 } 339} 340 341void 342v3dX(pipeline_pack_state)(struct v3dv_pipeline *pipeline, 343 const VkPipelineColorBlendStateCreateInfo *cb_info, 344 const VkPipelineDepthStencilStateCreateInfo *ds_info, 345 const VkPipelineRasterizationStateCreateInfo *rs_info, 346 const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info, 347 const VkPipelineMultisampleStateCreateInfo *ms_info) 348{ 349 pack_blend(pipeline, cb_info); 350 pack_cfg_bits(pipeline, ds_info, rs_info, pv_info, ms_info); 351 pack_stencil_cfg(pipeline, ds_info); 352} 353 354static void 355pack_shader_state_record(struct v3dv_pipeline *pipeline) 356{ 357 assert(sizeof(pipeline->shader_state_record) == 358 cl_packet_length(GL_SHADER_STATE_RECORD)); 359 360 struct v3d_fs_prog_data *prog_data_fs = 361 pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT]->prog_data.fs; 362 363 struct v3d_vs_prog_data *prog_data_vs = 364 pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX]->prog_data.vs; 365 366 struct v3d_vs_prog_data *prog_data_vs_bin = 367 pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX_BIN]->prog_data.vs; 368 369 370 /* Note: we are not packing addresses, as we need the job (see 371 * cl_pack_emit_reloc). Additionally uniforms can't be filled up at this 372 * point as they depend on dynamic info that can be set after create the 373 * pipeline (like viewport), . Would need to be filled later, so we are 374 * doing a partial prepacking. 375 */ 376 v3dvx_pack(pipeline->shader_state_record, GL_SHADER_STATE_RECORD, shader) { 377 shader.enable_clipping = true; 378 379 if (!pipeline->has_gs) { 380 shader.point_size_in_shaded_vertex_data = 381 pipeline->topology == PIPE_PRIM_POINTS; 382 } else { 383 struct v3d_gs_prog_data *prog_data_gs = 384 pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY]->prog_data.gs; 385 shader.point_size_in_shaded_vertex_data = prog_data_gs->writes_psiz; 386 } 387 388 /* Must be set if the shader modifies Z, discards, or modifies 389 * the sample mask. For any of these cases, the fragment 390 * shader needs to write the Z value (even just discards). 391 */ 392 shader.fragment_shader_does_z_writes = prog_data_fs->writes_z; 393 /* Set if the EZ test must be disabled (due to shader side 394 * effects and the early_z flag not being present in the 395 * shader). 396 */ 397 shader.turn_off_early_z_test = prog_data_fs->disable_ez; 398 399 shader.fragment_shader_uses_real_pixel_centre_w_in_addition_to_centroid_w2 = 400 prog_data_fs->uses_center_w; 401 402 /* The description for gl_SampleID states that if a fragment shader reads 403 * it, then we should automatically activate per-sample shading. However, 404 * the Vulkan spec also states that if a framebuffer has no attachments: 405 * 406 * "The subpass continues to use the width, height, and layers of the 407 * framebuffer to define the dimensions of the rendering area, and the 408 * rasterizationSamples from each pipeline’s 409 * VkPipelineMultisampleStateCreateInfo to define the number of 410 * samples used in rasterization multisample rasterization." 411 * 412 * So in this scenario, if the pipeline doesn't enable multiple samples 413 * but the fragment shader accesses gl_SampleID we would be requested 414 * to do per-sample shading in single sample rasterization mode, which 415 * is pointless, so just disable it in that case. 416 */ 417 shader.enable_sample_rate_shading = 418 pipeline->sample_rate_shading || 419 (pipeline->msaa && prog_data_fs->force_per_sample_msaa); 420 421 shader.any_shader_reads_hardware_written_primitive_id = false; 422 423 shader.do_scoreboard_wait_on_first_thread_switch = 424 prog_data_fs->lock_scoreboard_on_first_thrsw; 425 shader.disable_implicit_point_line_varyings = 426 !prog_data_fs->uses_implicit_point_line_varyings; 427 428 shader.number_of_varyings_in_fragment_shader = 429 prog_data_fs->num_inputs; 430 431 shader.coordinate_shader_propagate_nans = true; 432 shader.vertex_shader_propagate_nans = true; 433 shader.fragment_shader_propagate_nans = true; 434 435 /* Note: see previous note about adresses */ 436 /* shader.coordinate_shader_code_address */ 437 /* shader.vertex_shader_code_address */ 438 /* shader.fragment_shader_code_address */ 439 440 /* FIXME: Use combined input/output size flag in the common case (also 441 * on v3d, see v3dx_draw). 442 */ 443 shader.coordinate_shader_has_separate_input_and_output_vpm_blocks = 444 prog_data_vs_bin->separate_segments; 445 shader.vertex_shader_has_separate_input_and_output_vpm_blocks = 446 prog_data_vs->separate_segments; 447 448 shader.coordinate_shader_input_vpm_segment_size = 449 prog_data_vs_bin->separate_segments ? 450 prog_data_vs_bin->vpm_input_size : 1; 451 shader.vertex_shader_input_vpm_segment_size = 452 prog_data_vs->separate_segments ? 453 prog_data_vs->vpm_input_size : 1; 454 455 shader.coordinate_shader_output_vpm_segment_size = 456 prog_data_vs_bin->vpm_output_size; 457 shader.vertex_shader_output_vpm_segment_size = 458 prog_data_vs->vpm_output_size; 459 460 /* Note: see previous note about adresses */ 461 /* shader.coordinate_shader_uniforms_address */ 462 /* shader.vertex_shader_uniforms_address */ 463 /* shader.fragment_shader_uniforms_address */ 464 465 shader.min_coord_shader_input_segments_required_in_play = 466 pipeline->vpm_cfg_bin.As; 467 shader.min_vertex_shader_input_segments_required_in_play = 468 pipeline->vpm_cfg.As; 469 470 shader.min_coord_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size = 471 pipeline->vpm_cfg_bin.Ve; 472 shader.min_vertex_shader_output_segments_required_in_play_in_addition_to_vcm_cache_size = 473 pipeline->vpm_cfg.Ve; 474 475 shader.coordinate_shader_4_way_threadable = 476 prog_data_vs_bin->base.threads == 4; 477 shader.vertex_shader_4_way_threadable = 478 prog_data_vs->base.threads == 4; 479 shader.fragment_shader_4_way_threadable = 480 prog_data_fs->base.threads == 4; 481 482 shader.coordinate_shader_start_in_final_thread_section = 483 prog_data_vs_bin->base.single_seg; 484 shader.vertex_shader_start_in_final_thread_section = 485 prog_data_vs->base.single_seg; 486 shader.fragment_shader_start_in_final_thread_section = 487 prog_data_fs->base.single_seg; 488 489 shader.vertex_id_read_by_coordinate_shader = 490 prog_data_vs_bin->uses_vid; 491 shader.base_instance_id_read_by_coordinate_shader = 492 prog_data_vs_bin->uses_biid; 493 shader.instance_id_read_by_coordinate_shader = 494 prog_data_vs_bin->uses_iid; 495 shader.vertex_id_read_by_vertex_shader = 496 prog_data_vs->uses_vid; 497 shader.base_instance_id_read_by_vertex_shader = 498 prog_data_vs->uses_biid; 499 shader.instance_id_read_by_vertex_shader = 500 prog_data_vs->uses_iid; 501 502 /* Note: see previous note about adresses */ 503 /* shader.address_of_default_attribute_values */ 504 } 505} 506 507static void 508pack_vcm_cache_size(struct v3dv_pipeline *pipeline) 509{ 510 assert(sizeof(pipeline->vcm_cache_size) == 511 cl_packet_length(VCM_CACHE_SIZE)); 512 513 v3dvx_pack(pipeline->vcm_cache_size, VCM_CACHE_SIZE, vcm) { 514 vcm.number_of_16_vertex_batches_for_binning = pipeline->vpm_cfg_bin.Vc; 515 vcm.number_of_16_vertex_batches_for_rendering = pipeline->vpm_cfg.Vc; 516 } 517} 518 519/* As defined on the GL_SHADER_STATE_ATTRIBUTE_RECORD */ 520static uint8_t 521get_attr_type(const struct util_format_description *desc) 522{ 523 uint32_t r_size = desc->channel[0].size; 524 uint8_t attr_type = ATTRIBUTE_FLOAT; 525 526 switch (desc->channel[0].type) { 527 case UTIL_FORMAT_TYPE_FLOAT: 528 if (r_size == 32) { 529 attr_type = ATTRIBUTE_FLOAT; 530 } else { 531 assert(r_size == 16); 532 attr_type = ATTRIBUTE_HALF_FLOAT; 533 } 534 break; 535 536 case UTIL_FORMAT_TYPE_SIGNED: 537 case UTIL_FORMAT_TYPE_UNSIGNED: 538 switch (r_size) { 539 case 32: 540 attr_type = ATTRIBUTE_INT; 541 break; 542 case 16: 543 attr_type = ATTRIBUTE_SHORT; 544 break; 545 case 10: 546 attr_type = ATTRIBUTE_INT2_10_10_10; 547 break; 548 case 8: 549 attr_type = ATTRIBUTE_BYTE; 550 break; 551 default: 552 fprintf(stderr, 553 "format %s unsupported\n", 554 desc->name); 555 attr_type = ATTRIBUTE_BYTE; 556 abort(); 557 } 558 break; 559 560 default: 561 fprintf(stderr, 562 "format %s unsupported\n", 563 desc->name); 564 abort(); 565 } 566 567 return attr_type; 568} 569 570static void 571pack_shader_state_attribute_record(struct v3dv_pipeline *pipeline, 572 uint32_t index, 573 const VkVertexInputAttributeDescription *vi_desc) 574{ 575 const uint32_t packet_length = 576 cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD); 577 578 const struct util_format_description *desc = 579 vk_format_description(vi_desc->format); 580 581 uint32_t binding = vi_desc->binding; 582 583 v3dvx_pack(&pipeline->vertex_attrs[index * packet_length], 584 GL_SHADER_STATE_ATTRIBUTE_RECORD, attr) { 585 586 /* vec_size == 0 means 4 */ 587 attr.vec_size = desc->nr_channels & 3; 588 attr.signed_int_type = (desc->channel[0].type == 589 UTIL_FORMAT_TYPE_SIGNED); 590 attr.normalized_int_type = desc->channel[0].normalized; 591 attr.read_as_int_uint = desc->channel[0].pure_integer; 592 593 attr.instance_divisor = MIN2(pipeline->vb[binding].instance_divisor, 594 0xffff); 595 attr.stride = pipeline->vb[binding].stride; 596 attr.type = get_attr_type(desc); 597 } 598} 599 600void 601v3dX(pipeline_pack_compile_state)(struct v3dv_pipeline *pipeline, 602 const VkPipelineVertexInputStateCreateInfo *vi_info, 603 const VkPipelineVertexInputDivisorStateCreateInfoEXT *vd_info) 604{ 605 pack_shader_state_record(pipeline); 606 pack_vcm_cache_size(pipeline); 607 608 pipeline->vb_count = vi_info->vertexBindingDescriptionCount; 609 for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) { 610 const VkVertexInputBindingDescription *desc = 611 &vi_info->pVertexBindingDescriptions[i]; 612 613 pipeline->vb[desc->binding].stride = desc->stride; 614 pipeline->vb[desc->binding].instance_divisor = desc->inputRate; 615 } 616 617 if (vd_info) { 618 for (uint32_t i = 0; i < vd_info->vertexBindingDivisorCount; i++) { 619 const VkVertexInputBindingDivisorDescriptionEXT *desc = 620 &vd_info->pVertexBindingDivisors[i]; 621 622 pipeline->vb[desc->binding].instance_divisor = desc->divisor; 623 } 624 } 625 626 pipeline->va_count = 0; 627 struct v3d_vs_prog_data *prog_data_vs = 628 pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX]->prog_data.vs; 629 630 for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) { 631 const VkVertexInputAttributeDescription *desc = 632 &vi_info->pVertexAttributeDescriptions[i]; 633 uint32_t location = desc->location + VERT_ATTRIB_GENERIC0; 634 635 /* We use a custom driver_location_map instead of 636 * nir_find_variable_with_location because if we were able to get the 637 * shader variant from the cache, we would not have the nir shader 638 * available. 639 */ 640 uint32_t driver_location = 641 prog_data_vs->driver_location_map[location]; 642 643 if (driver_location != -1) { 644 assert(driver_location < MAX_VERTEX_ATTRIBS); 645 pipeline->va[driver_location].offset = desc->offset; 646 pipeline->va[driver_location].binding = desc->binding; 647 pipeline->va[driver_location].vk_format = desc->format; 648 649 pack_shader_state_attribute_record(pipeline, driver_location, desc); 650 651 pipeline->va_count++; 652 } 653 } 654} 655