1#include "vk_graphics_state.h" 2 3#include "vk_alloc.h" 4#include "vk_command_buffer.h" 5#include "vk_common_entrypoints.h" 6#include "vk_device.h" 7#include "vk_log.h" 8#include "vk_render_pass.h" 9#include "vk_standard_sample_locations.h" 10#include "vk_util.h" 11 12#include <assert.h> 13 14enum mesa_vk_graphics_state_groups { 15 MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT = (1 << 0), 16 MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT = (1 << 1), 17 MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT = (1 << 2), 18 MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT = (1 << 3), 19 MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT = (1 << 4), 20 MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT = (1 << 5), 21 MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT = (1 << 6), 22 MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT = (1 << 7), 23 MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT = (1 << 8), 24 MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT = (1 << 9), 25 MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT = (1 << 10), 26}; 27 28static void 29clear_all_dynamic_state(BITSET_WORD *dynamic) 30{ 31 /* Clear the whole array so there are no undefined bits at the top */ 32 memset(dynamic, 0, sizeof(*dynamic) * 33 BITSET_WORDS(MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX)); 34} 35 36static void 37get_dynamic_state_groups(BITSET_WORD *dynamic, 38 enum mesa_vk_graphics_state_groups groups) 39{ 40 clear_all_dynamic_state(dynamic); 41 42 if (groups & MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT) { 43 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VI); 44 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VI_BINDING_STRIDES); 45 } 46 47 if (groups & MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT) { 48 BITSET_SET(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY); 49 BITSET_SET(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE); 50 } 51 52 if (groups & MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT) 53 BITSET_SET(dynamic, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS); 54 55 if (groups & MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT) { 56 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT); 57 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_VIEWPORTS); 58 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_SCISSOR_COUNT); 59 BITSET_SET(dynamic, MESA_VK_DYNAMIC_VP_SCISSORS); 60 } 61 62 if (groups & MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT) 63 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DR_RECTANGLES); 64 65 if (groups & MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT) { 66 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE); 67 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_CULL_MODE); 68 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_FRONT_FACE); 69 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE); 70 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS); 71 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_LINE_WIDTH); 72 BITSET_SET(dynamic, MESA_VK_DYNAMIC_RS_LINE_STIPPLE); 73 } 74 75 if (groups & MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT) 76 BITSET_SET(dynamic, MESA_VK_DYNAMIC_FSR); 77 78 if (groups & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT) 79 BITSET_SET(dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS); 80 81 if (groups & MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT) { 82 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE); 83 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE); 84 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP); 85 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE); 86 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS); 87 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE); 88 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP); 89 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK); 90 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK); 91 BITSET_SET(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE); 92 } 93 94 if (groups & MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT) { 95 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_LOGIC_OP); 96 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES); 97 BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS); 98 } 99} 100 101static enum mesa_vk_graphics_state_groups 102fully_dynamic_state_groups(const BITSET_WORD *dynamic) 103{ 104 enum mesa_vk_graphics_state_groups groups = 0; 105 106 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_VI)) 107 groups |= MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT; 108 109 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) && 110 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE)) 111 groups |= MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT; 112 113 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_FSR)) 114 groups |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT; 115 116 if (BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) && 117 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) && 118 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP) && 119 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE) && 120 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS) && 121 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) && 122 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP) && 123 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) && 124 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) && 125 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) 126 groups |= MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT; 127 128 return groups; 129} 130 131static void 132validate_dynamic_state_groups(const BITSET_WORD *dynamic, 133 enum mesa_vk_graphics_state_groups groups) 134{ 135#ifndef NDEBUG 136 BITSET_DECLARE(all_dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); 137 get_dynamic_state_groups(all_dynamic, groups); 138 139 for (uint32_t w = 0; w < ARRAY_SIZE(all_dynamic); w++) 140 assert(!(dynamic[w] & ~all_dynamic[w])); 141#endif 142} 143 144void 145vk_get_dynamic_graphics_states(BITSET_WORD *dynamic, 146 const VkPipelineDynamicStateCreateInfo *info) 147{ 148 clear_all_dynamic_state(dynamic); 149 150 /* From the Vulkan 1.3.218 spec: 151 * 152 * "pDynamicState is a pointer to a VkPipelineDynamicStateCreateInfo 153 * structure defining which properties of the pipeline state object are 154 * dynamic and can be changed independently of the pipeline state. This 155 * can be NULL, which means no state in the pipeline is considered 156 * dynamic." 157 */ 158 if (info == NULL) 159 return; 160 161#define CASE(VK, MESA) \ 162 case VK_DYNAMIC_STATE_##VK: \ 163 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA); \ 164 break; 165 166#define CASE2(VK, MESA1, MESA2) \ 167 case VK_DYNAMIC_STATE_##VK: \ 168 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA1); \ 169 BITSET_SET(dynamic, MESA_VK_DYNAMIC_##MESA2); \ 170 break; 171 172 for (uint32_t i = 0; i < info->dynamicStateCount; i++) { 173 switch (info->pDynamicStates[i]) { 174 CASE2(VERTEX_INPUT_EXT, VI, VI_BINDING_STRIDES) 175 CASE( VERTEX_INPUT_BINDING_STRIDE, VI_BINDING_STRIDES) 176 CASE( VIEWPORT, VP_VIEWPORTS) 177 CASE( SCISSOR, VP_SCISSORS) 178 CASE( LINE_WIDTH, RS_LINE_WIDTH) 179 CASE( DEPTH_BIAS, RS_DEPTH_BIAS_FACTORS) 180 CASE( BLEND_CONSTANTS, CB_BLEND_CONSTANTS) 181 CASE( DEPTH_BOUNDS, DS_DEPTH_BOUNDS_TEST_BOUNDS) 182 CASE( STENCIL_COMPARE_MASK, DS_STENCIL_COMPARE_MASK) 183 CASE( STENCIL_WRITE_MASK, DS_STENCIL_WRITE_MASK) 184 CASE( STENCIL_REFERENCE, DS_STENCIL_REFERENCE) 185 CASE( CULL_MODE, RS_CULL_MODE) 186 CASE( FRONT_FACE, RS_FRONT_FACE) 187 CASE( PRIMITIVE_TOPOLOGY, IA_PRIMITIVE_TOPOLOGY) 188 CASE2(VIEWPORT_WITH_COUNT, VP_VIEWPORT_COUNT, VP_VIEWPORTS) 189 CASE2(SCISSOR_WITH_COUNT, VP_SCISSOR_COUNT, VP_SCISSORS) 190 CASE( DEPTH_TEST_ENABLE, DS_DEPTH_TEST_ENABLE) 191 CASE( DEPTH_WRITE_ENABLE, DS_DEPTH_WRITE_ENABLE) 192 CASE( DEPTH_COMPARE_OP, DS_DEPTH_COMPARE_OP) 193 CASE( DEPTH_BOUNDS_TEST_ENABLE, DS_DEPTH_BOUNDS_TEST_ENABLE) 194 CASE( STENCIL_TEST_ENABLE, DS_STENCIL_TEST_ENABLE) 195 CASE( STENCIL_OP, DS_STENCIL_OP) 196 CASE( RASTERIZER_DISCARD_ENABLE, RS_RASTERIZER_DISCARD_ENABLE) 197 CASE( DEPTH_BIAS_ENABLE, RS_DEPTH_BIAS_ENABLE) 198 CASE( PRIMITIVE_RESTART_ENABLE, IA_PRIMITIVE_RESTART_ENABLE) 199 CASE( DISCARD_RECTANGLE_EXT, DR_RECTANGLES) 200 CASE( SAMPLE_LOCATIONS_EXT, MS_SAMPLE_LOCATIONS) 201 CASE( FRAGMENT_SHADING_RATE_KHR, FSR) 202 CASE( LINE_STIPPLE_EXT, RS_LINE_STIPPLE) 203 CASE( PATCH_CONTROL_POINTS_EXT, TS_PATCH_CONTROL_POINTS) 204 CASE( LOGIC_OP_EXT, CB_LOGIC_OP) 205 CASE( COLOR_WRITE_ENABLE_EXT, CB_COLOR_WRITE_ENABLES) 206 default: 207 unreachable("Unsupported dynamic graphics state"); 208 } 209 } 210} 211 212#define IS_DYNAMIC(STATE) \ 213 BITSET_TEST(dynamic, MESA_VK_DYNAMIC_##STATE) 214 215#define IS_NEEDED(STATE) \ 216 BITSET_TEST(needed, MESA_VK_DYNAMIC_##STATE) 217 218static void 219vk_vertex_input_state_init(struct vk_vertex_input_state *vi, 220 const BITSET_WORD *dynamic, 221 const VkPipelineVertexInputStateCreateInfo *vi_info) 222{ 223 assert(!IS_DYNAMIC(VI)); 224 225 memset(vi, 0, sizeof(*vi)); 226 227 for (uint32_t i = 0; i < vi_info->vertexBindingDescriptionCount; i++) { 228 const VkVertexInputBindingDescription *desc = 229 &vi_info->pVertexBindingDescriptions[i]; 230 231 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS); 232 assert(desc->stride <= MESA_VK_MAX_VERTEX_BINDING_STRIDE); 233 assert(desc->inputRate <= 1); 234 235 const uint32_t b = desc->binding; 236 vi->bindings_valid |= BITFIELD_BIT(b); 237 vi->bindings[b].stride = desc->stride; 238 vi->bindings[b].input_rate = desc->inputRate; 239 vi->bindings[b].divisor = 1; 240 } 241 242 for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) { 243 const VkVertexInputAttributeDescription *desc = 244 &vi_info->pVertexAttributeDescriptions[i]; 245 246 assert(desc->location < MESA_VK_MAX_VERTEX_ATTRIBUTES); 247 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS); 248 assert(vi->bindings_valid & BITFIELD_BIT(desc->binding)); 249 250 const uint32_t a = desc->location; 251 vi->attributes_valid |= BITFIELD_BIT(a); 252 vi->attributes[a].binding = desc->binding; 253 vi->attributes[a].format = desc->format; 254 vi->attributes[a].offset = desc->offset; 255 } 256 257 const VkPipelineVertexInputDivisorStateCreateInfoEXT *vi_div_state = 258 vk_find_struct_const(vi_info->pNext, 259 PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT); 260 if (vi_div_state) { 261 for (uint32_t i = 0; i < vi_div_state->vertexBindingDivisorCount; i++) { 262 const VkVertexInputBindingDivisorDescriptionEXT *desc = 263 &vi_div_state->pVertexBindingDivisors[i]; 264 265 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS); 266 assert(vi->bindings_valid & BITFIELD_BIT(desc->binding)); 267 268 const uint32_t b = desc->binding; 269 vi->bindings[b].divisor = desc->divisor; 270 } 271 } 272} 273 274static void 275vk_dynamic_graphics_state_init_vi(struct vk_dynamic_graphics_state *dst, 276 const BITSET_WORD *needed, 277 const struct vk_vertex_input_state *vi) 278{ 279 if (IS_NEEDED(VI)) 280 *dst->vi = *vi; 281 282 if (IS_NEEDED(VI_BINDING_STRIDES)) { 283 for (uint32_t b = 0; b < MESA_VK_MAX_VERTEX_BINDINGS; b++) { 284 if (vi->bindings_valid & BITFIELD_BIT(b)) 285 dst->vi_binding_strides[b] = vi->bindings[b].stride; 286 else 287 dst->vi_binding_strides[b] = 0; 288 } 289 } 290} 291 292static void 293vk_input_assembly_state_init(struct vk_input_assembly_state *ia, 294 const BITSET_WORD *dynamic, 295 const VkPipelineInputAssemblyStateCreateInfo *ia_info) 296{ 297 if (IS_DYNAMIC(IA_PRIMITIVE_TOPOLOGY)) { 298 ia->primitive_topology = -1; 299 } else { 300 assert(ia_info->topology <= UINT8_MAX); 301 ia->primitive_topology = ia_info->topology; 302 } 303 304 ia->primitive_restart_enable = ia_info->primitiveRestartEnable; 305} 306 307static void 308vk_dynamic_graphics_state_init_ia(struct vk_dynamic_graphics_state *dst, 309 const BITSET_WORD *needed, 310 const struct vk_input_assembly_state *ia) 311{ 312 dst->ia = *ia; 313} 314 315static void 316vk_tessellation_state_init(struct vk_tessellation_state *ts, 317 const BITSET_WORD *dynamic, 318 const VkPipelineTessellationStateCreateInfo *ts_info) 319{ 320 if (IS_DYNAMIC(TS_PATCH_CONTROL_POINTS)) { 321 ts->patch_control_points = 0; 322 } else { 323 assert(ts_info->patchControlPoints <= UINT8_MAX); 324 ts->patch_control_points = ts_info->patchControlPoints; 325 } 326 327 const VkPipelineTessellationDomainOriginStateCreateInfo *ts_do_info = 328 vk_find_struct_const(ts_info->pNext, 329 PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO); 330 if (ts_do_info != NULL) { 331 assert(ts_do_info->domainOrigin <= UINT8_MAX); 332 ts->domain_origin = ts_do_info->domainOrigin; 333 } else { 334 ts->domain_origin = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT; 335 } 336} 337 338static void 339vk_dynamic_graphics_state_init_ts(struct vk_dynamic_graphics_state *dst, 340 const BITSET_WORD *needed, 341 const struct vk_tessellation_state *ts) 342{ 343 dst->ts.patch_control_points = ts->patch_control_points; 344} 345 346static void 347vk_viewport_state_init(struct vk_viewport_state *vp, 348 const BITSET_WORD *dynamic, 349 const VkPipelineViewportStateCreateInfo *vp_info) 350{ 351 memset(vp, 0, sizeof(*vp)); 352 353 if (!IS_DYNAMIC(VP_VIEWPORT_COUNT)) { 354 assert(vp_info->viewportCount <= MESA_VK_MAX_VIEWPORTS); 355 vp->viewport_count = vp_info->viewportCount; 356 } 357 358 if (!IS_DYNAMIC(VP_VIEWPORTS)) { 359 assert(!IS_DYNAMIC(VP_VIEWPORT_COUNT)); 360 typed_memcpy(vp->viewports, vp_info->pViewports, 361 vp_info->viewportCount); 362 } 363 364 if (!IS_DYNAMIC(VP_SCISSOR_COUNT)) { 365 assert(vp_info->scissorCount <= MESA_VK_MAX_SCISSORS); 366 vp->scissor_count = vp_info->scissorCount; 367 } 368 369 if (!IS_DYNAMIC(VP_SCISSORS)) { 370 assert(!IS_DYNAMIC(VP_SCISSOR_COUNT)); 371 typed_memcpy(vp->scissors, vp_info->pScissors, 372 vp_info->scissorCount); 373 } 374 375 const VkPipelineViewportDepthClipControlCreateInfoEXT *vp_dcc_info = 376 vk_find_struct_const(vp_info->pNext, 377 PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT); 378 if (vp_dcc_info != NULL) 379 vp->negative_one_to_one = vp_dcc_info->negativeOneToOne; 380} 381 382static void 383vk_dynamic_graphics_state_init_vp(struct vk_dynamic_graphics_state *dst, 384 const BITSET_WORD *needed, 385 const struct vk_viewport_state *vp) 386{ 387 dst->vp.viewport_count = vp->viewport_count; 388 if (IS_NEEDED(VP_VIEWPORTS)) 389 typed_memcpy(dst->vp.viewports, vp->viewports, vp->viewport_count); 390 391 dst->vp.scissor_count = vp->scissor_count; 392 if (IS_NEEDED(VP_SCISSORS)) 393 typed_memcpy(dst->vp.scissors, vp->scissors, vp->scissor_count); 394} 395 396static void 397vk_discard_rectangles_state_init(struct vk_discard_rectangles_state *dr, 398 const BITSET_WORD *dynamic, 399 const VkPipelineDiscardRectangleStateCreateInfoEXT *dr_info) 400{ 401 memset(dr, 0, sizeof(*dr)); 402 403 if (dr_info == NULL) 404 return; 405 406 dr->mode = dr_info->discardRectangleMode; 407 408 if (!IS_DYNAMIC(DR_RECTANGLES)) { 409 assert(dr_info->discardRectangleCount <= MESA_VK_MAX_DISCARD_RECTANGLES); 410 dr->rectangle_count = dr_info->discardRectangleCount; 411 typed_memcpy(dr->rectangles, dr_info->pDiscardRectangles, 412 dr_info->discardRectangleCount); 413 } 414} 415 416static void 417vk_dynamic_graphics_state_init_dr(struct vk_dynamic_graphics_state *dst, 418 const BITSET_WORD *needed, 419 const struct vk_discard_rectangles_state *dr) 420{ 421 dst->dr.rectangle_count = dr->rectangle_count; 422 typed_memcpy(dst->dr.rectangles, dr->rectangles, dr->rectangle_count); 423} 424 425static void 426vk_rasterization_state_init(struct vk_rasterization_state *rs, 427 const BITSET_WORD *dynamic, 428 const VkPipelineRasterizationStateCreateInfo *rs_info) 429{ 430 *rs = (struct vk_rasterization_state) { 431 .rasterizer_discard_enable = false, 432 .conservative_mode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT, 433 .rasterization_order_amd = VK_RASTERIZATION_ORDER_STRICT_AMD, 434 .provoking_vertex = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, 435 .line.mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, 436 }; 437 438 if (!IS_DYNAMIC(RS_RASTERIZER_DISCARD_ENABLE)) 439 rs->rasterizer_discard_enable = rs_info->rasterizerDiscardEnable; 440 441 /* From the Vulkan 1.3.218 spec: 442 * 443 * "If VkPipelineRasterizationDepthClipStateCreateInfoEXT is present in 444 * the graphics pipeline state then depth clipping is disabled if 445 * VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnable 446 * is VK_FALSE. Otherwise, if 447 * VkPipelineRasterizationDepthClipStateCreateInfoEXT is not present, 448 * depth clipping is disabled when 449 * VkPipelineRasterizationStateCreateInfo::depthClampEnable is VK_TRUE. 450 */ 451 rs->depth_clamp_enable = rs_info->depthClampEnable; 452 rs->depth_clip_enable = !rs_info->depthClampEnable; 453 454 rs->polygon_mode = rs_info->polygonMode; 455 456 rs->cull_mode = rs_info->cullMode; 457 rs->front_face = rs_info->frontFace; 458 rs->depth_bias.enable = rs_info->depthBiasEnable; 459 if ((rs_info->depthBiasEnable || IS_DYNAMIC(RS_DEPTH_BIAS_ENABLE)) && 460 !IS_DYNAMIC(RS_DEPTH_BIAS_FACTORS)) { 461 rs->depth_bias.constant = rs_info->depthBiasConstantFactor; 462 rs->depth_bias.clamp = rs_info->depthBiasClamp; 463 rs->depth_bias.slope = rs_info->depthBiasSlopeFactor; 464 } 465 rs->line.width = rs_info->lineWidth; 466 467 vk_foreach_struct_const(ext, rs_info->pNext) { 468 switch (ext->sType) { 469 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT: { 470 const VkPipelineRasterizationConservativeStateCreateInfoEXT *rcs_info = 471 (const VkPipelineRasterizationConservativeStateCreateInfoEXT *)ext; 472 rs->conservative_mode = rcs_info->conservativeRasterizationMode; 473 break; 474 } 475 476 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: { 477 const VkPipelineRasterizationDepthClipStateCreateInfoEXT *rdc_info = 478 (const VkPipelineRasterizationDepthClipStateCreateInfoEXT *)ext; 479 rs->depth_clip_enable = rdc_info->depthClipEnable; 480 break; 481 } 482 483 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT: { 484 const VkPipelineRasterizationLineStateCreateInfoEXT *rl_info = 485 (const VkPipelineRasterizationLineStateCreateInfoEXT *)ext; 486 rs->line.mode = rl_info->lineRasterizationMode; 487 rs->line.stipple.enable = rl_info->stippledLineEnable; 488 if (rs->line.stipple.enable && !IS_DYNAMIC(RS_LINE_STIPPLE)) { 489 rs->line.stipple.factor = rl_info->lineStippleFactor; 490 rs->line.stipple.pattern = rl_info->lineStipplePattern; 491 } 492 break; 493 } 494 495 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT: { 496 const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *rpv_info = 497 (const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *)ext; 498 rs->provoking_vertex = rpv_info->provokingVertexMode; 499 break; 500 } 501 502 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD: { 503 const VkPipelineRasterizationStateRasterizationOrderAMD *rro_info = 504 (const VkPipelineRasterizationStateRasterizationOrderAMD *)ext; 505 rs->rasterization_order_amd = rro_info->rasterizationOrder; 506 break; 507 } 508 509 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT: { 510 const VkPipelineRasterizationStateStreamCreateInfoEXT *rss_info = 511 (const VkPipelineRasterizationStateStreamCreateInfoEXT *)ext; 512 rs->rasterization_stream = rss_info->rasterizationStream; 513 break; 514 } 515 516 default: 517 break; 518 } 519 } 520} 521 522static void 523vk_dynamic_graphics_state_init_rs(struct vk_dynamic_graphics_state *dst, 524 const BITSET_WORD *needed, 525 const struct vk_rasterization_state *rs) 526{ 527 dst->rs.rasterizer_discard_enable = rs->rasterizer_discard_enable; 528 dst->rs.cull_mode = rs->cull_mode; 529 dst->rs.front_face = rs->front_face; 530 dst->rs.depth_bias.enable = rs->depth_bias.enable; 531 dst->rs.depth_bias.constant = rs->depth_bias.constant; 532 dst->rs.depth_bias.clamp = rs->depth_bias.clamp; 533 dst->rs.depth_bias.slope = rs->depth_bias.slope; 534 dst->rs.line.width = rs->line.width; 535 dst->rs.line.stipple.factor = rs->line.stipple.factor; 536 dst->rs.line.stipple.pattern = rs->line.stipple.pattern; 537} 538 539static void 540vk_fragment_shading_rate_state_init( 541 struct vk_fragment_shading_rate_state *fsr, 542 const BITSET_WORD *dynamic, 543 const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info) 544{ 545 if (fsr_info != NULL) { 546 fsr->fragment_size = fsr_info->fragmentSize; 547 fsr->combiner_ops[0] = fsr_info->combinerOps[0]; 548 fsr->combiner_ops[1] = fsr_info->combinerOps[1]; 549 } else { 550 fsr->fragment_size = (VkExtent2D) { 1, 1 }; 551 fsr->combiner_ops[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; 552 fsr->combiner_ops[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; 553 } 554} 555 556static void 557vk_dynamic_graphics_state_init_fsr( 558 struct vk_dynamic_graphics_state *dst, 559 const BITSET_WORD *needed, 560 const struct vk_fragment_shading_rate_state *fsr) 561{ 562 dst->fsr = *fsr; 563} 564 565static void 566vk_sample_locations_state_init(struct vk_sample_locations_state *sl, 567 const VkSampleLocationsInfoEXT *sl_info) 568{ 569 sl->per_pixel = sl_info->sampleLocationsPerPixel; 570 sl->grid_size = sl_info->sampleLocationGridSize; 571 572 /* From the Vulkan 1.3.218 spec: 573 * 574 * VUID-VkSampleLocationsInfoEXT-sampleLocationsCount-01527 575 * 576 * "sampleLocationsCount must equal sampleLocationsPerPixel * 577 * sampleLocationGridSize.width * sampleLocationGridSize.height" 578 */ 579 assert(sl_info->sampleLocationsCount == 580 sl_info->sampleLocationsPerPixel * 581 sl_info->sampleLocationGridSize.width * 582 sl_info->sampleLocationGridSize.height); 583 584 assert(sl_info->sampleLocationsCount <= MESA_VK_MAX_SAMPLE_LOCATIONS); 585 typed_memcpy(sl->locations, sl_info->pSampleLocations, 586 sl_info->sampleLocationsCount); 587} 588 589static void 590vk_multisample_state_init(struct vk_multisample_state *ms, 591 const BITSET_WORD *dynamic, 592 const VkPipelineMultisampleStateCreateInfo *ms_info) 593{ 594 ms->rasterization_samples = ms_info->rasterizationSamples; 595 ms->sample_shading_enable = ms_info->sampleShadingEnable; 596 ms->min_sample_shading = ms_info->minSampleShading; 597 598 /* From the Vulkan 1.3.218 spec: 599 * 600 * "If pSampleMask is NULL, it is treated as if the mask has all bits 601 * set to 1." 602 */ 603 ms->sample_mask = ms_info->pSampleMask ? *ms_info->pSampleMask : ~0; 604 605 ms->alpha_to_coverage_enable = ms_info->alphaToCoverageEnable; 606 ms->alpha_to_one_enable = ms_info->alphaToOneEnable; 607 608 /* These get filled in by vk_multisample_sample_locations_state_init() */ 609 ms->sample_locations_enable = false; 610 ms->sample_locations = NULL; 611} 612 613static bool 614needs_sample_locations_state( 615 const BITSET_WORD *dynamic, 616 const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info) 617{ 618 return !IS_DYNAMIC(MS_SAMPLE_LOCATIONS) && 619 sl_info != NULL && sl_info->sampleLocationsEnable; 620} 621 622static void 623vk_multisample_sample_locations_state_init( 624 struct vk_multisample_state *ms, 625 struct vk_sample_locations_state *sl, 626 const BITSET_WORD *dynamic, 627 const VkPipelineMultisampleStateCreateInfo *ms_info, 628 const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info) 629{ 630 ms->sample_locations_enable = 631 sl_info != NULL && sl_info->sampleLocationsEnable; 632 633 assert(ms->sample_locations == NULL); 634 if (!IS_DYNAMIC(MS_SAMPLE_LOCATIONS)) { 635 if (ms->sample_locations_enable) { 636 vk_sample_locations_state_init(sl, &sl_info->sampleLocationsInfo); 637 ms->sample_locations = sl; 638 } else { 639 /* Otherwise, pre-populate with the standard sample locations. If 640 * the driver doesn't support standard sample locations, it probably 641 * doesn't support custom locations either and can completely ignore 642 * this state. 643 */ 644 ms->sample_locations = 645 vk_standard_sample_locations_state(ms_info->rasterizationSamples); 646 } 647 } 648} 649 650static void 651vk_dynamic_graphics_state_init_ms(struct vk_dynamic_graphics_state *dst, 652 const BITSET_WORD *needed, 653 const struct vk_multisample_state *ms) 654{ 655 if (IS_NEEDED(MS_SAMPLE_LOCATIONS)) 656 *dst->ms.sample_locations = *ms->sample_locations; 657} 658 659static void 660vk_stencil_test_face_state_init(struct vk_stencil_test_face_state *face, 661 const VkStencilOpState *info) 662{ 663 face->op.fail = info->failOp; 664 face->op.pass = info->passOp; 665 face->op.depth_fail = info->depthFailOp; 666 face->op.compare = info->compareOp; 667 face->compare_mask = info->compareMask; 668 face->write_mask = info->writeMask; 669 face->reference = info->reference; 670} 671 672static void 673vk_depth_stencil_state_init(struct vk_depth_stencil_state *ds, 674 const BITSET_WORD *dynamic, 675 const VkPipelineDepthStencilStateCreateInfo *ds_info) 676{ 677 memset(ds, 0, sizeof(*ds)); 678 679 ds->depth.test_enable = ds_info->depthTestEnable; 680 ds->depth.write_enable = ds_info->depthWriteEnable; 681 ds->depth.compare_op = ds_info->depthCompareOp; 682 ds->depth.bounds_test.enable = ds_info->depthBoundsTestEnable; 683 ds->depth.bounds_test.min = ds_info->minDepthBounds; 684 ds->depth.bounds_test.max = ds_info->maxDepthBounds; 685 686 ds->stencil.test_enable = ds_info->stencilTestEnable; 687 ds->stencil.write_enable = true; 688 vk_stencil_test_face_state_init(&ds->stencil.front, &ds_info->front); 689 vk_stencil_test_face_state_init(&ds->stencil.back, &ds_info->back); 690} 691 692static void 693vk_dynamic_graphics_state_init_ds(struct vk_dynamic_graphics_state *dst, 694 const BITSET_WORD *needed, 695 const struct vk_depth_stencil_state *ds) 696{ 697 dst->ds = *ds; 698} 699 700static bool 701optimize_stencil_face(struct vk_stencil_test_face_state *face, 702 VkCompareOp depthCompareOp, 703 bool consider_write_mask) 704{ 705 /* If compareOp is ALWAYS then the stencil test will never fail and failOp 706 * will never happen. Set failOp to KEEP in this case. 707 */ 708 if (face->op.compare == VK_COMPARE_OP_ALWAYS) 709 face->op.fail = VK_STENCIL_OP_KEEP; 710 711 /* If compareOp is NEVER or depthCompareOp is NEVER then one of the depth 712 * or stencil tests will fail and passOp will never happen. 713 */ 714 if (face->op.compare == VK_COMPARE_OP_NEVER || 715 depthCompareOp == VK_COMPARE_OP_NEVER) 716 face->op.pass = VK_STENCIL_OP_KEEP; 717 718 /* If compareOp is NEVER or depthCompareOp is ALWAYS then either the 719 * stencil test will fail or the depth test will pass. In either case, 720 * depthFailOp will never happen. 721 */ 722 if (face->op.compare == VK_COMPARE_OP_NEVER || 723 depthCompareOp == VK_COMPARE_OP_ALWAYS) 724 face->op.depth_fail = VK_STENCIL_OP_KEEP; 725 726 /* If the write mask is zero, nothing will be written to the stencil buffer 727 * so it's as if all operations are KEEP. 728 */ 729 if (consider_write_mask && face->write_mask == 0) { 730 face->op.pass = VK_STENCIL_OP_KEEP; 731 face->op.fail = VK_STENCIL_OP_KEEP; 732 face->op.depth_fail = VK_STENCIL_OP_KEEP; 733 } 734 735 return face->op.fail != VK_STENCIL_OP_KEEP || 736 face->op.depth_fail != VK_STENCIL_OP_KEEP || 737 face->op.pass != VK_STENCIL_OP_KEEP; 738} 739 740void 741vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds, 742 VkImageAspectFlags ds_aspects, 743 bool consider_write_mask) 744{ 745 /* stencil.write_enable is a dummy right now that should always be true */ 746 assert(ds->stencil.write_enable); 747 748 /* From the Vulkan 1.3.221 spec: 749 * 750 * "If there is no depth attachment then the depth test is skipped." 751 */ 752 if (!(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) 753 ds->depth.test_enable = false; 754 755 /* From the Vulkan 1.3.221 spec: 756 * 757 * "...or if there is no stencil attachment, the coverage mask is 758 * unmodified by this operation." 759 */ 760 if (!(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) 761 ds->stencil.test_enable = false; 762 763 /* If the depth test is disabled, we won't be writing anything. Make sure we 764 * treat the test as always passing later on as well. 765 */ 766 if (!ds->depth.test_enable) { 767 ds->depth.write_enable = false; 768 ds->depth.compare_op = VK_COMPARE_OP_ALWAYS; 769 } 770 771 /* If the stencil test is disabled, we won't be writing anything. Make sure 772 * we treat the test as always passing later on as well. 773 */ 774 if (!ds->stencil.test_enable) { 775 ds->stencil.write_enable = false; 776 ds->stencil.front.op.compare = VK_COMPARE_OP_ALWAYS; 777 ds->stencil.back.op.compare = VK_COMPARE_OP_ALWAYS; 778 } 779 780 /* If the stencil test is enabled and always fails, then we will never get 781 * to the depth test so we can just disable the depth test entirely. 782 */ 783 if (ds->stencil.test_enable && 784 ds->stencil.front.op.compare == VK_COMPARE_OP_NEVER && 785 ds->stencil.back.op.compare == VK_COMPARE_OP_NEVER) { 786 ds->depth.test_enable = false; 787 ds->depth.write_enable = false; 788 } 789 790 /* If depthCompareOp is EQUAL then the value we would be writing to the 791 * depth buffer is the same as the value that's already there so there's no 792 * point in writing it. 793 */ 794 if (ds->depth.compare_op == VK_COMPARE_OP_EQUAL) 795 ds->depth.write_enable = false; 796 797 /* If the stencil ops are such that we don't actually ever modify the 798 * stencil buffer, we should disable writes. 799 */ 800 if (!optimize_stencil_face(&ds->stencil.front, ds->depth.compare_op, 801 consider_write_mask) && 802 !optimize_stencil_face(&ds->stencil.back, ds->depth.compare_op, 803 consider_write_mask)) 804 ds->stencil.write_enable = false; 805 806 /* If the depth test always passes and we never write out depth, that's the 807 * same as if the depth test is disabled entirely. 808 */ 809 if (ds->depth.compare_op == VK_COMPARE_OP_ALWAYS && !ds->depth.write_enable) 810 ds->depth.test_enable = false; 811 812 /* If the stencil test always passes and we never write out stencil, that's 813 * the same as if the stencil test is disabled entirely. 814 */ 815 if (ds->stencil.front.op.compare == VK_COMPARE_OP_ALWAYS && 816 ds->stencil.back.op.compare == VK_COMPARE_OP_ALWAYS && 817 !ds->stencil.write_enable) 818 ds->stencil.test_enable = false; 819} 820 821static void 822vk_color_blend_state_init(struct vk_color_blend_state *cb, 823 const BITSET_WORD *dynamic, 824 const VkPipelineColorBlendStateCreateInfo *cb_info) 825{ 826 memset(cb, 0, sizeof(*cb)); 827 828 cb->logic_op_enable = cb_info->logicOpEnable; 829 cb->logic_op = cb_info->logicOp; 830 831 assert(cb_info->attachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS); 832 cb->attachment_count = cb_info->attachmentCount; 833 for (uint32_t a = 0; a < cb_info->attachmentCount; a++) { 834 const VkPipelineColorBlendAttachmentState *att = 835 &cb_info->pAttachments[a]; 836 837 cb->attachments[a] = (struct vk_color_blend_attachment_state) { 838 .blend_enable = att->blendEnable, 839 .src_color_blend_factor = att->srcColorBlendFactor, 840 .dst_color_blend_factor = att->dstColorBlendFactor, 841 .src_alpha_blend_factor = att->srcAlphaBlendFactor, 842 .dst_alpha_blend_factor = att->dstAlphaBlendFactor, 843 .write_mask = att->colorWriteMask, 844 .color_blend_op = att->colorBlendOp, 845 .alpha_blend_op = att->alphaBlendOp, 846 }; 847 } 848 849 for (uint32_t i = 0; i < 4; i++) 850 cb->blend_constants[i] = cb_info->blendConstants[i]; 851 852 const VkPipelineColorWriteCreateInfoEXT *cw_info = 853 vk_find_struct_const(cb_info->pNext, PIPELINE_COLOR_WRITE_CREATE_INFO_EXT); 854 if (cw_info != NULL) { 855 assert(cb_info->attachmentCount == cw_info->attachmentCount); 856 for (uint32_t a = 0; a < cw_info->attachmentCount; a++) { 857 if (cw_info->pColorWriteEnables[a]) 858 cb->color_write_enables |= BITFIELD_BIT(a); 859 } 860 } else { 861 cb->color_write_enables = BITFIELD_MASK(cb_info->attachmentCount); 862 } 863} 864 865static void 866vk_dynamic_graphics_state_init_cb(struct vk_dynamic_graphics_state *dst, 867 const BITSET_WORD *needed, 868 const struct vk_color_blend_state *cb) 869{ 870 dst->cb.logic_op = cb->logic_op; 871 dst->cb.color_write_enables = cb->color_write_enables; 872 873 if (IS_NEEDED(CB_BLEND_CONSTANTS)) 874 typed_memcpy(dst->cb.blend_constants, cb->blend_constants, 4); 875} 876 877static bool 878vk_render_pass_state_is_complete(const struct vk_render_pass_state *rp) 879{ 880 return rp->attachment_aspects != VK_IMAGE_ASPECT_METADATA_BIT; 881} 882 883static void 884vk_render_pass_state_init(struct vk_render_pass_state *rp, 885 const struct vk_render_pass_state *old_rp, 886 const VkGraphicsPipelineCreateInfo *info, 887 const struct vk_subpass_info *sp_info, 888 VkGraphicsPipelineLibraryFlagsEXT lib) 889{ 890 /* If we already have render pass state and it has attachment info, then 891 * it's complete and we don't need a new one. 892 */ 893 if (old_rp != NULL && vk_render_pass_state_is_complete(old_rp)) { 894 *rp = *old_rp; 895 return; 896 } 897 898 *rp = (struct vk_render_pass_state) { 899 .render_pass = info->renderPass, 900 .subpass = info->subpass, 901 .depth_attachment_format = VK_FORMAT_UNDEFINED, 902 .stencil_attachment_format = VK_FORMAT_UNDEFINED, 903 }; 904 905 if (info->renderPass != VK_NULL_HANDLE && sp_info != NULL) { 906 rp->attachment_aspects = sp_info->attachment_aspects; 907 rp->view_mask = sp_info->view_mask; 908 return; 909 } 910 911 const VkPipelineRenderingCreateInfo *r_info = 912 vk_get_pipeline_rendering_create_info(info); 913 914 if (r_info == NULL) 915 return; 916 917 rp->view_mask = r_info->viewMask; 918 919 /* From the Vulkan 1.3.218 spec description of pre-rasterization state: 920 * 921 * "Fragment shader state is defined by: 922 * ... 923 * * VkRenderPass and subpass parameter 924 * * The viewMask parameter of VkPipelineRenderingCreateInfo (formats 925 * are ignored)" 926 * 927 * The description of fragment shader state contains identical text. 928 * 929 * If we have a render pass then we have full information. Even if we're 930 * dynamic-rendering-only, the presence of a render pass means the 931 * rendering info came from a vk_render_pass and is therefore complete. 932 * Otherwise, all we can grab is the view mask and we have to leave the 933 * rest for later. 934 */ 935 if (info->renderPass == VK_NULL_HANDLE && 936 !(lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) { 937 rp->attachment_aspects = VK_IMAGE_ASPECT_METADATA_BIT; 938 return; 939 } 940 941 assert(r_info->colorAttachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS); 942 rp->color_attachment_count = r_info->colorAttachmentCount; 943 for (uint32_t i = 0; i < r_info->colorAttachmentCount; i++) { 944 rp->color_attachment_formats[i] = r_info->pColorAttachmentFormats[i]; 945 if (r_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED) 946 rp->attachment_aspects |= VK_IMAGE_ASPECT_COLOR_BIT; 947 } 948 949 rp->depth_attachment_format = r_info->depthAttachmentFormat; 950 if (r_info->depthAttachmentFormat != VK_FORMAT_UNDEFINED) 951 rp->attachment_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; 952 953 rp->stencil_attachment_format = r_info->stencilAttachmentFormat; 954 if (r_info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED) 955 rp->attachment_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; 956 957 const VkRenderingSelfDependencyInfoMESA *rsd_info = 958 vk_find_struct_const(r_info->pNext, RENDERING_SELF_DEPENDENCY_INFO_MESA); 959 if (rsd_info != NULL) { 960 STATIC_ASSERT(sizeof(rp->color_self_dependencies) * 8 >= 961 MESA_VK_MAX_COLOR_ATTACHMENTS); 962 rp->color_self_dependencies = rsd_info->colorSelfDependencies; 963 rp->depth_self_dependency = rsd_info->depthSelfDependency; 964 rp->stencil_self_dependency = rsd_info->stencilSelfDependency; 965 } 966} 967 968static void 969vk_dynamic_graphics_state_init_rp(struct vk_dynamic_graphics_state *dst, 970 const BITSET_WORD *needed, 971 const struct vk_render_pass_state *rp) 972{ } 973 974#define FOREACH_STATE_GROUP(f) \ 975 f(MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT, \ 976 vk_vertex_input_state, vi); \ 977 f(MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT, \ 978 vk_input_assembly_state, ia); \ 979 f(MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT, \ 980 vk_tessellation_state, ts); \ 981 f(MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT, \ 982 vk_viewport_state, vp); \ 983 f(MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT, \ 984 vk_discard_rectangles_state, dr); \ 985 f(MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT, \ 986 vk_rasterization_state, rs); \ 987 f(MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT, \ 988 vk_fragment_shading_rate_state, fsr); \ 989 f(MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT, \ 990 vk_multisample_state, ms); \ 991 f(MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT, \ 992 vk_depth_stencil_state, ds); \ 993 f(MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT, \ 994 vk_color_blend_state, cb); \ 995 f(MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT, \ 996 vk_render_pass_state, rp); 997 998static enum mesa_vk_graphics_state_groups 999vk_graphics_pipeline_state_groups(const struct vk_graphics_pipeline_state *state) 1000{ 1001 /* For now, we just validate dynamic state */ 1002 enum mesa_vk_graphics_state_groups groups = 0; 1003 1004#define FILL_HAS(STATE, type, s) \ 1005 if (state->s != NULL) groups |= STATE 1006 1007 FOREACH_STATE_GROUP(FILL_HAS) 1008 1009#undef FILL_HAS 1010 1011 return groups | fully_dynamic_state_groups(state->dynamic); 1012} 1013 1014static void 1015vk_graphics_pipeline_state_validate(const struct vk_graphics_pipeline_state *state) 1016{ 1017#ifndef NDEBUG 1018 /* For now, we just validate dynamic state */ 1019 enum mesa_vk_graphics_state_groups groups = 1020 vk_graphics_pipeline_state_groups(state); 1021 validate_dynamic_state_groups(state->dynamic, groups); 1022#endif 1023} 1024 1025static bool 1026may_have_rasterization(const struct vk_graphics_pipeline_state *state, 1027 const BITSET_WORD *dynamic, 1028 const VkGraphicsPipelineCreateInfo *info) 1029{ 1030 if (state->rs) { 1031 /* We default rasterizer_discard_enable to false when dynamic */ 1032 return !state->rs->rasterizer_discard_enable; 1033 } else { 1034 return IS_DYNAMIC(RS_RASTERIZER_DISCARD_ENABLE) || 1035 !info->pRasterizationState->rasterizerDiscardEnable; 1036 } 1037} 1038 1039VkResult 1040vk_graphics_pipeline_state_fill(const struct vk_device *device, 1041 struct vk_graphics_pipeline_state *state, 1042 const VkGraphicsPipelineCreateInfo *info, 1043 const struct vk_subpass_info *sp_info, 1044 struct vk_graphics_pipeline_all_state *all, 1045 const VkAllocationCallbacks *alloc, 1046 VkSystemAllocationScope scope, 1047 void **alloc_ptr_out) 1048{ 1049 vk_graphics_pipeline_state_validate(state); 1050 1051 BITSET_DECLARE(dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); 1052 vk_get_dynamic_graphics_states(dynamic, info->pDynamicState); 1053 1054 for (uint32_t i = 0; i < info->stageCount; i++) 1055 state->shader_stages |= info->pStages[i].stage; 1056 1057 /* In case we return early */ 1058 if (alloc_ptr_out != NULL) 1059 *alloc_ptr_out = NULL; 1060 1061 /* 1062 * First, figure out which library-level shader/state groups we need 1063 */ 1064 1065 VkGraphicsPipelineLibraryFlagsEXT lib; 1066 if (info->flags & VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) { 1067 const VkGraphicsPipelineLibraryCreateInfoEXT *gfx_lib_info = 1068 vk_find_struct_const(info->pNext, GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT); 1069 lib = gfx_lib_info->flags; 1070 } else { 1071 /* We're building a complete pipeline. From the Vulkan 1.3.218 spec: 1072 * 1073 * "A complete graphics pipeline always includes pre-rasterization 1074 * shader state, with other subsets included depending on that state. 1075 * If the pre-rasterization shader state includes a vertex shader, 1076 * then vertex input state is included in a complete graphics 1077 * pipeline. If the value of 1078 * VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable in 1079 * the pre-rasterization shader state is VK_FALSE or the 1080 * VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE dynamic state is 1081 * enabled fragment shader state and fragment output interface state 1082 * is included in a complete graphics pipeline." 1083 */ 1084 lib = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT; 1085 1086 if (state->shader_stages & VK_SHADER_STAGE_VERTEX_BIT) 1087 lib |= VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT; 1088 1089 if (may_have_rasterization(state, dynamic, info)) { 1090 lib |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT; 1091 lib |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT; 1092 } 1093 } 1094 1095 /* 1096 * Next, turn those into individual states. Among other things, this 1097 * de-duplicates things like FSR and multisample state which appear in 1098 * multiple library groups. 1099 */ 1100 1101 enum mesa_vk_graphics_state_groups needs = 0; 1102 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) { 1103 needs |= MESA_VK_GRAPHICS_STATE_VERTEX_INPUT_BIT; 1104 needs |= MESA_VK_GRAPHICS_STATE_INPUT_ASSEMBLY_BIT; 1105 } 1106 1107 /* Other stuff potentially depends on this so gather it early */ 1108 struct vk_render_pass_state rp; 1109 if (lib & (VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT | 1110 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT | 1111 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) { 1112 vk_render_pass_state_init(&rp, state->rp, info, sp_info, lib); 1113 1114 needs |= MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT; 1115 1116 /* If the old state was incomplete but the new one isn't, set state->rp 1117 * to NULL so it gets replaced with the new version. 1118 */ 1119 if (state->rp != NULL && 1120 !vk_render_pass_state_is_complete(state->rp) && 1121 vk_render_pass_state_is_complete(&rp)) 1122 state->rp = NULL; 1123 } 1124 1125 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) { 1126 /* From the Vulkan 1.3.218 spec: 1127 * 1128 * VUID-VkGraphicsPipelineCreateInfo-stage-02096 1129 * 1130 * "If the pipeline is being created with pre-rasterization shader 1131 * state the stage member of one element of pStages must be either 1132 * VK_SHADER_STAGE_VERTEX_BIT or VK_SHADER_STAGE_MESH_BIT_NV" 1133 */ 1134 assert(state->shader_stages & (VK_SHADER_STAGE_VERTEX_BIT | 1135 VK_SHADER_STAGE_MESH_BIT_NV)); 1136 1137 if (state->shader_stages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | 1138 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) 1139 needs |= MESA_VK_GRAPHICS_STATE_TESSELLATION_BIT; 1140 1141 if (may_have_rasterization(state, dynamic, info)) 1142 needs |= MESA_VK_GRAPHICS_STATE_VIEWPORT_BIT; 1143 1144 needs |= MESA_VK_GRAPHICS_STATE_DISCARD_RECTANGLES_BIT; 1145 needs |= MESA_VK_GRAPHICS_STATE_RASTERIZATION_BIT; 1146 needs |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT; 1147 } 1148 1149 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) { 1150 needs |= MESA_VK_GRAPHICS_STATE_FRAGMENT_SHADING_RATE_BIT; 1151 1152 /* From the Vulkan 1.3.218 spec: 1153 * 1154 * "Fragment shader state is defined by: 1155 * ... 1156 * - VkPipelineMultisampleStateCreateInfo if sample shading is 1157 * enabled or renderpass is not VK_NULL_HANDLE" 1158 * 1159 * and 1160 * 1161 * VUID-VkGraphicsPipelineCreateInfo-pMultisampleState-06629 1162 * 1163 * "If the pipeline is being created with fragment shader state 1164 * pMultisampleState must be NULL or a valid pointer to a valid 1165 * VkPipelineMultisampleStateCreateInfo structure" 1166 * 1167 * so we can reliably detect when to include it based on the 1168 * pMultisampleState pointer. 1169 */ 1170 if (info->pMultisampleState != NULL) 1171 needs |= MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT; 1172 1173 /* From the Vulkan 1.3.218 spec: 1174 * 1175 * VUID-VkGraphicsPipelineCreateInfo-renderPass-06043 1176 * 1177 * "If renderPass is not VK_NULL_HANDLE, the pipeline is being 1178 * created with fragment shader state, and subpass uses a 1179 * depth/stencil attachment, pDepthStencilState must be a valid 1180 * pointer to a valid VkPipelineDepthStencilStateCreateInfo 1181 * structure" 1182 * 1183 * VUID-VkGraphicsPipelineCreateInfo-renderPass-06053 1184 * 1185 * "If renderPass is VK_NULL_HANDLE, the pipeline is being created 1186 * with fragment shader state and fragment output interface state, 1187 * and either of VkPipelineRenderingCreateInfo::depthAttachmentFormat 1188 * or VkPipelineRenderingCreateInfo::stencilAttachmentFormat are not 1189 * VK_FORMAT_UNDEFINED, pDepthStencilState must be a valid pointer to 1190 * a valid VkPipelineDepthStencilStateCreateInfo structure" 1191 * 1192 * VUID-VkGraphicsPipelineCreateInfo-renderPass-06590 1193 * 1194 * "If renderPass is VK_NULL_HANDLE and the pipeline is being created 1195 * with fragment shader state but not fragment output interface 1196 * state, pDepthStencilState must be a valid pointer to a valid 1197 * VkPipelineDepthStencilStateCreateInfo structure" 1198 * 1199 * In the first case, we'll have a real set of aspects in rp. In the 1200 * second case, where we have both fragment shader and fragment output 1201 * state, we will also have a valid set of aspects. In the third case 1202 * where we only have fragment shader state and no render pass, the 1203 * vk_render_pass_state will be incomplete. 1204 */ 1205 if ((rp.attachment_aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | 1206 VK_IMAGE_ASPECT_STENCIL_BIT)) || 1207 !vk_render_pass_state_is_complete(&rp)) 1208 needs |= MESA_VK_GRAPHICS_STATE_DEPTH_STENCIL_BIT; 1209 } 1210 1211 if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) { 1212 if (rp.attachment_aspects & (VK_IMAGE_ASPECT_COLOR_BIT)) 1213 needs |= MESA_VK_GRAPHICS_STATE_COLOR_BLEND_BIT; 1214 1215 needs |= MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT; 1216 } 1217 1218 /* 1219 * Next, Filter off any states we already have. 1220 */ 1221 1222#define FILTER_NEEDS(STATE, type, s) \ 1223 if (state->s != NULL) needs &= ~STATE 1224 1225 FOREACH_STATE_GROUP(FILTER_NEEDS) 1226 1227#undef FILTER_NEEDS 1228 1229 /* Filter dynamic state down to just what we're adding */ 1230 BITSET_DECLARE(dynamic_filter, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); 1231 get_dynamic_state_groups(dynamic_filter, needs); 1232 BITSET_AND(dynamic, dynamic, dynamic_filter); 1233 1234 /* And add it in */ 1235 BITSET_OR(state->dynamic, state->dynamic, dynamic); 1236 1237 /* 1238 * If a state is fully dynamic, we don't need to even allocate them. Do 1239 * this after we've filtered dynamic state because we still want them to 1240 * show up in the dynamic state but don't want the actual state. 1241 */ 1242 needs &= ~fully_dynamic_state_groups(state->dynamic); 1243 1244 /* If we don't need to set up any new states, bail early */ 1245 if (needs == 0) 1246 return VK_SUCCESS; 1247 1248 /* 1249 * Now, ensure that we have space for each of the states we're going to 1250 * fill. If all != NULL, we'll pull from that. Otherwise, we need to 1251 * allocate memory. 1252 */ 1253 1254 VK_MULTIALLOC(ma); 1255 1256#define ENSURE_STATE_IF_NEEDED(STATE, type, s) \ 1257 struct type *new_##s = NULL; \ 1258 if (needs & STATE) { \ 1259 if (all == NULL) { \ 1260 vk_multialloc_add(&ma, &new_##s, struct type, 1); \ 1261 } else { \ 1262 new_##s = &all->s; \ 1263 } \ 1264 } 1265 1266 FOREACH_STATE_GROUP(ENSURE_STATE_IF_NEEDED) 1267 1268#undef ENSURE_STATE_IF_NEEDED 1269 1270 /* Sample locations are a bit special. We don't want to waste the memory 1271 * for 64 floats if we don't need to. Also, we set up standard sample 1272 * locations if no user-provided sample locations are available. 1273 */ 1274 const VkPipelineSampleLocationsStateCreateInfoEXT *sl_info = NULL; 1275 struct vk_sample_locations_state *new_sl = NULL; 1276 if (needs & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT) { 1277 sl_info = vk_find_struct_const(info->pMultisampleState->pNext, 1278 PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT); 1279 if (needs_sample_locations_state(dynamic, sl_info)) { 1280 if (all == NULL) { 1281 vk_multialloc_add(&ma, &new_sl, struct vk_sample_locations_state, 1); 1282 } else { 1283 new_sl = &all->ms_sample_locations; 1284 } 1285 } 1286 } 1287 1288 /* 1289 * Allocate memory, if needed 1290 */ 1291 1292 if (ma.size > 0) { 1293 assert(all == NULL); 1294 *alloc_ptr_out = vk_multialloc_alloc2(&ma, &device->alloc, alloc, scope); 1295 if (*alloc_ptr_out == NULL) 1296 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1297 } 1298 1299 /* 1300 * Create aliases for various input infos so we can use or FOREACH macro 1301 */ 1302 1303#define INFO_ALIAS(_State, s) \ 1304 const VkPipeline##_State##StateCreateInfo *s##_info = info->p##_State##State 1305 1306 INFO_ALIAS(VertexInput, vi); 1307 INFO_ALIAS(InputAssembly, ia); 1308 INFO_ALIAS(Tessellation, ts); 1309 INFO_ALIAS(Viewport, vp); 1310 INFO_ALIAS(Rasterization, rs); 1311 INFO_ALIAS(Multisample, ms); 1312 INFO_ALIAS(DepthStencil, ds); 1313 INFO_ALIAS(ColorBlend, cb); 1314 1315#undef INFO_ALIAS 1316 1317 const VkPipelineDiscardRectangleStateCreateInfoEXT *dr_info = 1318 vk_find_struct_const(info->pNext, PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT); 1319 1320 const VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_info = 1321 vk_find_struct_const(info->pNext, PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR); 1322 1323 /* 1324 * Finally, fill out all the states 1325 */ 1326 1327#define INIT_STATE_IF_NEEDED(STATE, type, s) \ 1328 if (needs & STATE) { \ 1329 type##_init(new_##s, dynamic, s##_info); \ 1330 state->s = new_##s; \ 1331 } 1332 1333 /* render pass state is special and we just copy it */ 1334#define vk_render_pass_state_init(s, d, i) *s = rp 1335 1336 FOREACH_STATE_GROUP(INIT_STATE_IF_NEEDED) 1337 1338#undef vk_render_pass_state_init 1339#undef INIT_STATE_IF_NEEDED 1340 1341 if (needs & MESA_VK_GRAPHICS_STATE_MULTISAMPLE_BIT) { 1342 vk_multisample_sample_locations_state_init(new_ms, new_sl, dynamic, 1343 ms_info, sl_info); 1344 } 1345 1346 return VK_SUCCESS; 1347} 1348 1349#undef IS_DYNAMIC 1350#undef IS_NEEDED 1351 1352void 1353vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst, 1354 const struct vk_graphics_pipeline_state *src) 1355{ 1356 vk_graphics_pipeline_state_validate(dst); 1357 vk_graphics_pipeline_state_validate(src); 1358 1359 BITSET_OR(dst->dynamic, dst->dynamic, src->dynamic); 1360 1361 dst->shader_stages |= src->shader_stages; 1362 1363 /* Render pass state needs special care because a render pass state may be 1364 * incomplete (view mask only). See vk_render_pass_state_init(). 1365 */ 1366 if (dst->rp != NULL && src->rp != NULL && 1367 !vk_render_pass_state_is_complete(dst->rp) && 1368 vk_render_pass_state_is_complete(src->rp)) 1369 dst->rp = src->rp; 1370 1371#define MERGE(STATE, type, state) \ 1372 if (dst->state == NULL && src->state != NULL) dst->state = src->state; 1373 1374 FOREACH_STATE_GROUP(MERGE) 1375 1376#undef MERGE 1377} 1378 1379const struct vk_dynamic_graphics_state vk_default_dynamic_graphics_state = { 1380 .rs = { 1381 .line = { 1382 .width = 1.0f, 1383 }, 1384 }, 1385 .fsr = { 1386 .fragment_size = {1u, 1u}, 1387 .combiner_ops = { 1388 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, 1389 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, 1390 }, 1391 }, 1392 .ds = { 1393 .depth = { 1394 .bounds_test = { 1395 .min = 0.0f, 1396 .max = 1.0f, 1397 }, 1398 }, 1399 .stencil = { 1400 .write_enable = true, 1401 .front = { 1402 .compare_mask = -1, 1403 .write_mask = -1, 1404 }, 1405 .back = { 1406 .compare_mask = -1, 1407 .write_mask = -1, 1408 }, 1409 }, 1410 }, 1411 .cb = { 1412 .color_write_enables = 0xffffffffu, 1413 }, 1414}; 1415 1416void 1417vk_dynamic_graphics_state_init(struct vk_dynamic_graphics_state *dyn) 1418{ 1419 *dyn = vk_default_dynamic_graphics_state; 1420} 1421 1422void 1423vk_dynamic_graphics_state_clear(struct vk_dynamic_graphics_state *dyn) 1424{ 1425 struct vk_vertex_input_state *vi = dyn->vi; 1426 struct vk_sample_locations_state *sl = dyn->ms.sample_locations; 1427 1428 *dyn = vk_default_dynamic_graphics_state; 1429 1430 if (vi != NULL) { 1431 memset(vi, 0, sizeof(*vi)); 1432 dyn->vi = vi; 1433 } 1434 1435 if (sl != NULL) { 1436 memset(sl, 0, sizeof(*sl)); 1437 dyn->ms.sample_locations = sl; 1438 } 1439} 1440 1441void 1442vk_dynamic_graphics_state_fill(struct vk_dynamic_graphics_state *dyn, 1443 const struct vk_graphics_pipeline_state *p) 1444{ 1445 /* This funciton (and the individual vk_dynamic_graphics_state_init_* 1446 * functions it calls) are a bit sloppy. Instead of checking every single 1447 * bit, we just copy everything and set the bits the right way at the end 1448 * based on what groups we actually had. 1449 */ 1450 enum mesa_vk_graphics_state_groups groups = 0; 1451 1452 BITSET_DECLARE(needed, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); 1453 BITSET_COPY(needed, p->dynamic); 1454 BITSET_NOT(needed); 1455 1456 /* We only want to copy these if the driver has filled out the relevant 1457 * pointer in the dynamic state struct. If not, they don't support them 1458 * as dynamic state and we should leave them alone. 1459 */ 1460 if (dyn->vi == NULL) 1461 BITSET_CLEAR(needed, MESA_VK_DYNAMIC_VI); 1462 if (dyn->ms.sample_locations == NULL) 1463 BITSET_CLEAR(needed, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS); 1464 1465#define INIT_DYNAMIC_STATE(STATE, type, s) \ 1466 if (p->s != NULL) { \ 1467 vk_dynamic_graphics_state_init_##s(dyn, needed, p->s); \ 1468 groups |= STATE; \ 1469 } 1470 1471 FOREACH_STATE_GROUP(INIT_DYNAMIC_STATE); 1472 1473#undef INIT_DYNAMIC_STATE 1474 1475 /* Mask off all but the groups we actually found */ 1476 get_dynamic_state_groups(dyn->set, groups); 1477 BITSET_AND(dyn->set, dyn->set, needed); 1478} 1479 1480#define SET_DYN_VALUE(dst, STATE, state, value) do { \ 1481 if (!BITSET_TEST((dst)->set, MESA_VK_DYNAMIC_##STATE) || \ 1482 (dst)->state != (value)) { \ 1483 (dst)->state = (value); \ 1484 assert((dst)->state == (value)); \ 1485 BITSET_SET(dst->set, MESA_VK_DYNAMIC_##STATE); \ 1486 BITSET_SET(dst->dirty, MESA_VK_DYNAMIC_##STATE); \ 1487 } \ 1488} while(0) 1489 1490#define SET_DYN_BOOL(dst, STATE, state, value) \ 1491 SET_DYN_VALUE(dst, STATE, state, (bool)value); 1492 1493#define SET_DYN_ARRAY(dst, STATE, state, start, count, src) do { \ 1494 assert(start + count <= ARRAY_SIZE((dst)->state)); \ 1495 STATIC_ASSERT(sizeof(*(dst)->state) == sizeof(*(src))); \ 1496 const size_t __state_size = sizeof(*(dst)->state) * (count); \ 1497 if (!BITSET_TEST((dst)->set, MESA_VK_DYNAMIC_##STATE) || \ 1498 memcmp((dst)->state + start, src, __state_size)) { \ 1499 memcpy((dst)->state + start, src, __state_size); \ 1500 BITSET_SET(dst->set, MESA_VK_DYNAMIC_##STATE); \ 1501 BITSET_SET(dst->dirty, MESA_VK_DYNAMIC_##STATE); \ 1502 } \ 1503} while(0) 1504 1505void 1506vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state *dst, 1507 const struct vk_dynamic_graphics_state *src) 1508{ 1509#define IS_SET_IN_SRC(STATE) \ 1510 BITSET_TEST(src->set, MESA_VK_DYNAMIC_##STATE) 1511 1512#define COPY_MEMBER(STATE, state) \ 1513 SET_DYN_VALUE(dst, STATE, state, src->state) 1514 1515#define COPY_ARRAY(STATE, state, count) \ 1516 SET_DYN_ARRAY(dst, STATE, state, 0, count, src->state) 1517 1518#define COPY_IF_SET(STATE, state) \ 1519 if (IS_SET_IN_SRC(STATE)) SET_DYN_VALUE(dst, STATE, state, src->state) 1520 1521 assert((dst->vi != NULL) == (src->vi != NULL)); 1522 if (dst->vi != NULL && IS_SET_IN_SRC(VI)) { 1523 COPY_MEMBER(VI, vi->bindings_valid); 1524 u_foreach_bit(b, src->vi->bindings_valid) { 1525 COPY_MEMBER(VI, vi->bindings[b].stride); 1526 COPY_MEMBER(VI, vi->bindings[b].input_rate); 1527 COPY_MEMBER(VI, vi->bindings[b].divisor); 1528 } 1529 COPY_MEMBER(VI, vi->attributes_valid); 1530 u_foreach_bit(a, src->vi->attributes_valid) { 1531 COPY_MEMBER(VI, vi->attributes[a].binding); 1532 COPY_MEMBER(VI, vi->attributes[a].format); 1533 COPY_MEMBER(VI, vi->attributes[a].offset); 1534 } 1535 } 1536 1537 if (IS_SET_IN_SRC(VI_BINDING_STRIDES)) { 1538 COPY_ARRAY(VI_BINDING_STRIDES, vi_binding_strides, 1539 MESA_VK_MAX_VERTEX_BINDINGS); 1540 } 1541 1542 COPY_IF_SET(IA_PRIMITIVE_TOPOLOGY, ia.primitive_topology); 1543 COPY_IF_SET(IA_PRIMITIVE_RESTART_ENABLE, ia.primitive_restart_enable); 1544 COPY_IF_SET(TS_PATCH_CONTROL_POINTS, ts.patch_control_points); 1545 1546 COPY_IF_SET(VP_VIEWPORT_COUNT, vp.viewport_count); 1547 if (IS_SET_IN_SRC(VP_VIEWPORTS)) { 1548 assert(IS_SET_IN_SRC(VP_VIEWPORT_COUNT)); 1549 COPY_ARRAY(VP_VIEWPORTS, vp.viewports, src->vp.viewport_count); 1550 } 1551 1552 COPY_IF_SET(VP_SCISSOR_COUNT, vp.scissor_count); 1553 if (IS_SET_IN_SRC(VP_SCISSORS)) { 1554 assert(IS_SET_IN_SRC(VP_SCISSOR_COUNT)); 1555 COPY_ARRAY(VP_SCISSORS, vp.scissors, src->vp.scissor_count); 1556 } 1557 1558 if (IS_SET_IN_SRC(DR_RECTANGLES)) { 1559 COPY_MEMBER(DR_RECTANGLES, dr.rectangle_count); 1560 COPY_ARRAY(DR_RECTANGLES, dr.rectangles, src->dr.rectangle_count); 1561 } 1562 1563 COPY_IF_SET(RS_RASTERIZER_DISCARD_ENABLE, rs.rasterizer_discard_enable); 1564 COPY_IF_SET(RS_CULL_MODE, rs.cull_mode); 1565 COPY_IF_SET(RS_FRONT_FACE, rs.front_face); 1566 COPY_IF_SET(RS_DEPTH_BIAS_ENABLE, rs.depth_bias.enable); 1567 COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.constant); 1568 COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.clamp); 1569 COPY_IF_SET(RS_DEPTH_BIAS_FACTORS, rs.depth_bias.slope); 1570 COPY_IF_SET(RS_LINE_WIDTH, rs.line.width); 1571 COPY_IF_SET(RS_LINE_STIPPLE, rs.line.stipple.factor); 1572 COPY_IF_SET(RS_LINE_STIPPLE, rs.line.stipple.pattern); 1573 1574 COPY_IF_SET(FSR, fsr.fragment_size.width); 1575 COPY_IF_SET(FSR, fsr.fragment_size.height); 1576 COPY_IF_SET(FSR, fsr.combiner_ops[0]); 1577 COPY_IF_SET(FSR, fsr.combiner_ops[1]); 1578 1579 assert((dst->ms.sample_locations == NULL) == 1580 (src->ms.sample_locations == NULL)); 1581 if (dst->ms.sample_locations != NULL && 1582 IS_SET_IN_SRC(MS_SAMPLE_LOCATIONS)) { 1583 COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->per_pixel); 1584 COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->grid_size.width); 1585 COPY_MEMBER(MS_SAMPLE_LOCATIONS, ms.sample_locations->grid_size.height); 1586 const uint32_t sl_count = src->ms.sample_locations->per_pixel * 1587 src->ms.sample_locations->grid_size.width * 1588 src->ms.sample_locations->grid_size.height; 1589 COPY_ARRAY(MS_SAMPLE_LOCATIONS, ms.sample_locations->locations, sl_count); 1590 } 1591 1592 COPY_IF_SET(DS_DEPTH_TEST_ENABLE, ds.depth.test_enable); 1593 COPY_IF_SET(DS_DEPTH_WRITE_ENABLE, ds.depth.write_enable); 1594 COPY_IF_SET(DS_DEPTH_COMPARE_OP, ds.depth.compare_op); 1595 COPY_IF_SET(DS_DEPTH_BOUNDS_TEST_ENABLE, ds.depth.bounds_test.enable); 1596 if (IS_SET_IN_SRC(DS_DEPTH_BOUNDS_TEST_BOUNDS)) { 1597 COPY_MEMBER(DS_DEPTH_BOUNDS_TEST_BOUNDS, ds.depth.bounds_test.min); 1598 COPY_MEMBER(DS_DEPTH_BOUNDS_TEST_BOUNDS, ds.depth.bounds_test.max); 1599 } 1600 1601 COPY_IF_SET(DS_STENCIL_TEST_ENABLE, ds.stencil.test_enable); 1602 if (IS_SET_IN_SRC(DS_STENCIL_OP)) { 1603 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.fail); 1604 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.pass); 1605 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.depth_fail); 1606 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.front.op.compare); 1607 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.fail); 1608 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.pass); 1609 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.depth_fail); 1610 COPY_MEMBER(DS_STENCIL_OP, ds.stencil.back.op.compare); 1611 } 1612 if (IS_SET_IN_SRC(DS_STENCIL_COMPARE_MASK)) { 1613 COPY_MEMBER(DS_STENCIL_COMPARE_MASK, ds.stencil.front.compare_mask); 1614 COPY_MEMBER(DS_STENCIL_COMPARE_MASK, ds.stencil.back.compare_mask); 1615 } 1616 if (IS_SET_IN_SRC(DS_STENCIL_WRITE_MASK)) { 1617 COPY_MEMBER(DS_STENCIL_WRITE_MASK, ds.stencil.front.write_mask); 1618 COPY_MEMBER(DS_STENCIL_WRITE_MASK, ds.stencil.back.write_mask); 1619 } 1620 if (IS_SET_IN_SRC(DS_STENCIL_REFERENCE)) { 1621 COPY_MEMBER(DS_STENCIL_REFERENCE, ds.stencil.front.reference); 1622 COPY_MEMBER(DS_STENCIL_REFERENCE, ds.stencil.back.reference); 1623 } 1624 1625 COPY_IF_SET(CB_LOGIC_OP, cb.logic_op); 1626 COPY_IF_SET(CB_COLOR_WRITE_ENABLES, cb.color_write_enables); 1627 if (IS_SET_IN_SRC(CB_BLEND_CONSTANTS)) 1628 COPY_ARRAY(CB_BLEND_CONSTANTS, cb.blend_constants, 4); 1629 1630#undef IS_SET_IN_SRC 1631#undef MARK_DIRTY 1632#undef COPY_MEMBER 1633#undef COPY_ARRAY 1634#undef COPY_IF_SET 1635 1636 for (uint32_t w = 0; w < ARRAY_SIZE(dst->dirty); w++) { 1637 /* If it's in the source but isn't set in the destination at all, mark 1638 * it dirty. It's possible that the default values just happen to equal 1639 * the value from src. 1640 */ 1641 dst->dirty[w] |= src->set[w] & ~dst->set[w]; 1642 1643 /* Everything that was in the source is now in the destination */ 1644 dst->set[w] |= src->set[w]; 1645 } 1646} 1647 1648void 1649vk_cmd_set_dynamic_graphics_state(struct vk_command_buffer *cmd, 1650 const struct vk_dynamic_graphics_state *state) 1651{ 1652 vk_dynamic_graphics_state_copy(&cmd->dynamic_graphics_state, state); 1653} 1654 1655VKAPI_ATTR void VKAPI_CALL 1656vk_common_CmdSetVertexInputEXT(VkCommandBuffer commandBuffer, 1657 uint32_t vertexBindingDescriptionCount, 1658 const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, 1659 uint32_t vertexAttributeDescriptionCount, 1660 const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions) 1661{ 1662 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1663 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1664 1665 uint32_t bindings_valid = 0; 1666 for (uint32_t i = 0; i < vertexBindingDescriptionCount; i++) { 1667 const VkVertexInputBindingDescription2EXT *desc = 1668 &pVertexBindingDescriptions[i]; 1669 1670 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS); 1671 assert(desc->stride <= MESA_VK_MAX_VERTEX_BINDING_STRIDE); 1672 assert(desc->inputRate <= UINT8_MAX); 1673 1674 const uint32_t b = desc->binding; 1675 bindings_valid |= BITFIELD_BIT(b); 1676 SET_DYN_VALUE(dyn, VI, vi->bindings[b].stride, desc->stride); 1677 SET_DYN_VALUE(dyn, VI, vi->bindings[b].input_rate, desc->inputRate); 1678 SET_DYN_VALUE(dyn, VI, vi->bindings[b].divisor, desc->divisor); 1679 1680 /* Also set bindings_strides in case a driver is keying off that */ 1681 SET_DYN_VALUE(dyn, VI_BINDING_STRIDES, 1682 vi_binding_strides[b], desc->stride); 1683 } 1684 SET_DYN_VALUE(dyn, VI, vi->bindings_valid, bindings_valid); 1685 1686 uint32_t attributes_valid = 0; 1687 for (uint32_t i = 0; i < vertexAttributeDescriptionCount; i++) { 1688 const VkVertexInputAttributeDescription2EXT *desc = 1689 &pVertexAttributeDescriptions[i]; 1690 1691 assert(desc->location < MESA_VK_MAX_VERTEX_ATTRIBUTES); 1692 assert(desc->binding < MESA_VK_MAX_VERTEX_BINDINGS); 1693 assert(bindings_valid & BITFIELD_BIT(desc->binding)); 1694 1695 const uint32_t a = desc->location; 1696 attributes_valid |= BITFIELD_BIT(a); 1697 SET_DYN_VALUE(dyn, VI, vi->attributes[a].binding, desc->binding); 1698 SET_DYN_VALUE(dyn, VI, vi->attributes[a].format, desc->format); 1699 SET_DYN_VALUE(dyn, VI, vi->attributes[a].offset, desc->offset); 1700 } 1701 SET_DYN_VALUE(dyn, VI, vi->attributes_valid, attributes_valid); 1702} 1703 1704void 1705vk_cmd_set_vertex_binding_strides(struct vk_command_buffer *cmd, 1706 uint32_t first_binding, 1707 uint32_t binding_count, 1708 const VkDeviceSize *strides) 1709{ 1710 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1711 1712 for (uint32_t i = 0; i < binding_count; i++) { 1713 SET_DYN_VALUE(dyn, VI_BINDING_STRIDES, 1714 vi_binding_strides[first_binding + i], strides[i]); 1715 } 1716} 1717 1718VKAPI_ATTR void VKAPI_CALL 1719vk_common_CmdSetPrimitiveTopology(VkCommandBuffer commandBuffer, 1720 VkPrimitiveTopology primitiveTopology) 1721{ 1722 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1723 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1724 1725 SET_DYN_VALUE(dyn, IA_PRIMITIVE_TOPOLOGY, 1726 ia.primitive_topology, primitiveTopology); 1727} 1728 1729VKAPI_ATTR void VKAPI_CALL 1730vk_common_CmdSetPrimitiveRestartEnable(VkCommandBuffer commandBuffer, 1731 VkBool32 primitiveRestartEnable) 1732{ 1733 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1734 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1735 1736 SET_DYN_BOOL(dyn, IA_PRIMITIVE_RESTART_ENABLE, 1737 ia.primitive_restart_enable, primitiveRestartEnable); 1738} 1739 1740VKAPI_ATTR void VKAPI_CALL 1741vk_common_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer, 1742 uint32_t patchControlPoints) 1743{ 1744 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1745 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1746 1747 SET_DYN_VALUE(dyn, TS_PATCH_CONTROL_POINTS, 1748 ts.patch_control_points, patchControlPoints); 1749} 1750 1751VKAPI_ATTR void VKAPI_CALL 1752vk_common_CmdSetViewport(VkCommandBuffer commandBuffer, 1753 uint32_t firstViewport, 1754 uint32_t viewportCount, 1755 const VkViewport *pViewports) 1756{ 1757 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1758 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1759 1760 SET_DYN_ARRAY(dyn, VP_VIEWPORTS, vp.viewports, 1761 firstViewport, viewportCount, pViewports); 1762} 1763 1764VKAPI_ATTR void VKAPI_CALL 1765vk_common_CmdSetViewportWithCount(VkCommandBuffer commandBuffer, 1766 uint32_t viewportCount, 1767 const VkViewport *pViewports) 1768{ 1769 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1770 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1771 1772 SET_DYN_VALUE(dyn, VP_VIEWPORT_COUNT, vp.viewport_count, viewportCount); 1773 SET_DYN_ARRAY(dyn, VP_VIEWPORTS, vp.viewports, 0, viewportCount, pViewports); 1774} 1775 1776VKAPI_ATTR void VKAPI_CALL 1777vk_common_CmdSetScissor(VkCommandBuffer commandBuffer, 1778 uint32_t firstScissor, 1779 uint32_t scissorCount, 1780 const VkRect2D *pScissors) 1781{ 1782 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1783 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1784 1785 SET_DYN_ARRAY(dyn, VP_SCISSORS, vp.scissors, 1786 firstScissor, scissorCount, pScissors); 1787} 1788 1789VKAPI_ATTR void VKAPI_CALL 1790vk_common_CmdSetScissorWithCount(VkCommandBuffer commandBuffer, 1791 uint32_t scissorCount, 1792 const VkRect2D *pScissors) 1793{ 1794 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1795 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1796 1797 SET_DYN_VALUE(dyn, VP_SCISSOR_COUNT, vp.scissor_count, scissorCount); 1798 SET_DYN_ARRAY(dyn, VP_SCISSORS, vp.scissors, 0, scissorCount, pScissors); 1799} 1800 1801VKAPI_ATTR void VKAPI_CALL 1802vk_common_CmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, 1803 uint32_t firstDiscardRectangle, 1804 uint32_t discardRectangleCount, 1805 const VkRect2D *pDiscardRectangles) 1806{ 1807 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1808 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1809 1810 SET_DYN_VALUE(dyn, DR_RECTANGLES, dr.rectangle_count, discardRectangleCount); 1811 SET_DYN_ARRAY(dyn, DR_RECTANGLES, dr.rectangles, firstDiscardRectangle, 1812 discardRectangleCount, pDiscardRectangles); 1813} 1814 1815VKAPI_ATTR void VKAPI_CALL 1816vk_common_CmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer, 1817 VkBool32 rasterizerDiscardEnable) 1818{ 1819 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1820 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1821 1822 SET_DYN_BOOL(dyn, RS_RASTERIZER_DISCARD_ENABLE, 1823 rs.rasterizer_discard_enable, rasterizerDiscardEnable); 1824} 1825 1826VKAPI_ATTR void VKAPI_CALL 1827vk_common_CmdSetCullMode(VkCommandBuffer commandBuffer, 1828 VkCullModeFlags cullMode) 1829{ 1830 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1831 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1832 1833 SET_DYN_VALUE(dyn, RS_CULL_MODE, rs.cull_mode, cullMode); 1834} 1835 1836VKAPI_ATTR void VKAPI_CALL 1837vk_common_CmdSetFrontFace(VkCommandBuffer commandBuffer, 1838 VkFrontFace frontFace) 1839{ 1840 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1841 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1842 1843 SET_DYN_VALUE(dyn, RS_FRONT_FACE, rs.front_face, frontFace); 1844} 1845 1846VKAPI_ATTR void VKAPI_CALL 1847vk_common_CmdSetDepthBiasEnable(VkCommandBuffer commandBuffer, 1848 VkBool32 depthBiasEnable) 1849{ 1850 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1851 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1852 1853 SET_DYN_BOOL(dyn, RS_DEPTH_BIAS_ENABLE, 1854 rs.depth_bias.enable, depthBiasEnable); 1855} 1856 1857VKAPI_ATTR void VKAPI_CALL 1858vk_common_CmdSetDepthBias(VkCommandBuffer commandBuffer, 1859 float depthBiasConstantFactor, 1860 float depthBiasClamp, 1861 float depthBiasSlopeFactor) 1862{ 1863 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1864 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1865 1866 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS, 1867 rs.depth_bias.constant, depthBiasConstantFactor); 1868 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS, 1869 rs.depth_bias.clamp, depthBiasClamp); 1870 SET_DYN_VALUE(dyn, RS_DEPTH_BIAS_FACTORS, 1871 rs.depth_bias.slope, depthBiasSlopeFactor); 1872} 1873 1874VKAPI_ATTR void VKAPI_CALL 1875vk_common_CmdSetLineWidth(VkCommandBuffer commandBuffer, 1876 float lineWidth) 1877{ 1878 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1879 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1880 1881 SET_DYN_VALUE(dyn, RS_LINE_WIDTH, rs.line.width, lineWidth); 1882} 1883 1884VKAPI_ATTR void VKAPI_CALL 1885vk_common_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer, 1886 uint32_t lineStippleFactor, 1887 uint16_t lineStipplePattern) 1888{ 1889 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1890 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1891 1892 SET_DYN_VALUE(dyn, RS_LINE_STIPPLE, 1893 rs.line.stipple.factor, lineStippleFactor); 1894 SET_DYN_VALUE(dyn, RS_LINE_STIPPLE, 1895 rs.line.stipple.pattern, lineStipplePattern); 1896} 1897 1898VKAPI_ATTR void VKAPI_CALL 1899vk_common_CmdSetFragmentShadingRateKHR(VkCommandBuffer commandBuffer, 1900 const VkExtent2D *pFragmentSize, 1901 const VkFragmentShadingRateCombinerOpKHR combinerOps[2]) 1902{ 1903 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1904 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1905 1906 SET_DYN_VALUE(dyn, FSR, fsr.fragment_size.width, pFragmentSize->width); 1907 SET_DYN_VALUE(dyn, FSR, fsr.fragment_size.height, pFragmentSize->height); 1908 SET_DYN_VALUE(dyn, FSR, fsr.combiner_ops[0], combinerOps[0]); 1909 SET_DYN_VALUE(dyn, FSR, fsr.combiner_ops[1], combinerOps[1]); 1910} 1911 1912VKAPI_ATTR void VKAPI_CALL 1913vk_common_CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer, 1914 const VkSampleLocationsInfoEXT *pSampleLocationsInfo) 1915{ 1916 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1917 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1918 1919 SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS, 1920 ms.sample_locations->per_pixel, 1921 pSampleLocationsInfo->sampleLocationsPerPixel); 1922 SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS, 1923 ms.sample_locations->grid_size.width, 1924 pSampleLocationsInfo->sampleLocationGridSize.width); 1925 SET_DYN_VALUE(dyn, MS_SAMPLE_LOCATIONS, 1926 ms.sample_locations->grid_size.height, 1927 pSampleLocationsInfo->sampleLocationGridSize.height); 1928 1929 assert(pSampleLocationsInfo->sampleLocationsCount == 1930 pSampleLocationsInfo->sampleLocationsPerPixel * 1931 pSampleLocationsInfo->sampleLocationGridSize.width * 1932 pSampleLocationsInfo->sampleLocationGridSize.height); 1933 1934 assert(pSampleLocationsInfo->sampleLocationsCount <= 1935 MESA_VK_MAX_SAMPLE_LOCATIONS); 1936 1937 SET_DYN_ARRAY(dyn, MS_SAMPLE_LOCATIONS, 1938 ms.sample_locations->locations, 1939 0, pSampleLocationsInfo->sampleLocationsCount, 1940 pSampleLocationsInfo->pSampleLocations); 1941} 1942 1943VKAPI_ATTR void VKAPI_CALL 1944vk_common_CmdSetDepthTestEnable(VkCommandBuffer commandBuffer, 1945 VkBool32 depthTestEnable) 1946{ 1947 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1948 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1949 1950 SET_DYN_BOOL(dyn, DS_DEPTH_TEST_ENABLE, 1951 ds.depth.test_enable, depthTestEnable); 1952} 1953 1954VKAPI_ATTR void VKAPI_CALL 1955vk_common_CmdSetDepthWriteEnable(VkCommandBuffer commandBuffer, 1956 VkBool32 depthWriteEnable) 1957{ 1958 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1959 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1960 1961 SET_DYN_BOOL(dyn, DS_DEPTH_WRITE_ENABLE, 1962 ds.depth.write_enable, depthWriteEnable); 1963} 1964 1965VKAPI_ATTR void VKAPI_CALL 1966vk_common_CmdSetDepthCompareOp(VkCommandBuffer commandBuffer, 1967 VkCompareOp depthCompareOp) 1968{ 1969 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1970 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1971 1972 SET_DYN_VALUE(dyn, DS_DEPTH_COMPARE_OP, ds.depth.compare_op, 1973 depthCompareOp); 1974} 1975 1976VKAPI_ATTR void VKAPI_CALL 1977vk_common_CmdSetDepthBoundsTestEnable(VkCommandBuffer commandBuffer, 1978 VkBool32 depthBoundsTestEnable) 1979{ 1980 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1981 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1982 1983 SET_DYN_BOOL(dyn, DS_DEPTH_BOUNDS_TEST_ENABLE, 1984 ds.depth.bounds_test.enable, depthBoundsTestEnable); 1985} 1986 1987VKAPI_ATTR void VKAPI_CALL 1988vk_common_CmdSetDepthBounds(VkCommandBuffer commandBuffer, 1989 float minDepthBounds, 1990 float maxDepthBounds) 1991{ 1992 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 1993 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 1994 1995 SET_DYN_VALUE(dyn, DS_DEPTH_BOUNDS_TEST_BOUNDS, 1996 ds.depth.bounds_test.min, minDepthBounds); 1997 SET_DYN_VALUE(dyn, DS_DEPTH_BOUNDS_TEST_BOUNDS, 1998 ds.depth.bounds_test.max, maxDepthBounds); 1999} 2000 2001VKAPI_ATTR void VKAPI_CALL 2002vk_common_CmdSetStencilTestEnable(VkCommandBuffer commandBuffer, 2003 VkBool32 stencilTestEnable) 2004{ 2005 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 2006 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 2007 2008 SET_DYN_BOOL(dyn, DS_STENCIL_TEST_ENABLE, 2009 ds.stencil.test_enable, stencilTestEnable); 2010} 2011 2012VKAPI_ATTR void VKAPI_CALL 2013vk_common_CmdSetStencilOp(VkCommandBuffer commandBuffer, 2014 VkStencilFaceFlags faceMask, 2015 VkStencilOp failOp, 2016 VkStencilOp passOp, 2017 VkStencilOp depthFailOp, 2018 VkCompareOp compareOp) 2019{ 2020 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 2021 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 2022 2023 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { 2024 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.fail, failOp); 2025 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.pass, passOp); 2026 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.depth_fail, depthFailOp); 2027 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.front.op.compare, compareOp); 2028 } 2029 2030 if (faceMask & VK_STENCIL_FACE_BACK_BIT) { 2031 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.fail, failOp); 2032 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.pass, passOp); 2033 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.depth_fail, depthFailOp); 2034 SET_DYN_VALUE(dyn, DS_STENCIL_OP, ds.stencil.back.op.compare, compareOp); 2035 } 2036} 2037 2038VKAPI_ATTR void VKAPI_CALL 2039vk_common_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, 2040 VkStencilFaceFlags faceMask, 2041 uint32_t compareMask) 2042{ 2043 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 2044 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 2045 2046 /* We assume 8-bit stencil always */ 2047 STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1); 2048 2049 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { 2050 SET_DYN_VALUE(dyn, DS_STENCIL_COMPARE_MASK, 2051 ds.stencil.front.compare_mask, (uint8_t)compareMask); 2052 } 2053 if (faceMask & VK_STENCIL_FACE_BACK_BIT) { 2054 SET_DYN_VALUE(dyn, DS_STENCIL_COMPARE_MASK, 2055 ds.stencil.back.compare_mask, (uint8_t)compareMask); 2056 } 2057} 2058 2059VKAPI_ATTR void VKAPI_CALL 2060vk_common_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, 2061 VkStencilFaceFlags faceMask, 2062 uint32_t writeMask) 2063{ 2064 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 2065 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 2066 2067 /* We assume 8-bit stencil always */ 2068 STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1); 2069 2070 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { 2071 SET_DYN_VALUE(dyn, DS_STENCIL_WRITE_MASK, 2072 ds.stencil.front.write_mask, (uint8_t)writeMask); 2073 } 2074 if (faceMask & VK_STENCIL_FACE_BACK_BIT) { 2075 SET_DYN_VALUE(dyn, DS_STENCIL_WRITE_MASK, 2076 ds.stencil.back.write_mask, (uint8_t)writeMask); 2077 } 2078} 2079 2080VKAPI_ATTR void VKAPI_CALL 2081vk_common_CmdSetStencilReference(VkCommandBuffer commandBuffer, 2082 VkStencilFaceFlags faceMask, 2083 uint32_t reference) 2084{ 2085 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 2086 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 2087 2088 /* We assume 8-bit stencil always */ 2089 STATIC_ASSERT(sizeof(dyn->ds.stencil.front.write_mask) == 1); 2090 2091 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { 2092 SET_DYN_VALUE(dyn, DS_STENCIL_REFERENCE, 2093 ds.stencil.front.reference, (uint8_t)reference); 2094 } 2095 if (faceMask & VK_STENCIL_FACE_BACK_BIT) { 2096 SET_DYN_VALUE(dyn, DS_STENCIL_REFERENCE, 2097 ds.stencil.back.reference, (uint8_t)reference); 2098 } 2099} 2100 2101VKAPI_ATTR void VKAPI_CALL 2102vk_common_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer, 2103 VkLogicOp logicOp) 2104{ 2105 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 2106 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 2107 2108 SET_DYN_VALUE(dyn, CB_LOGIC_OP, cb.logic_op, logicOp); 2109} 2110 2111VKAPI_ATTR void VKAPI_CALL 2112vk_common_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer, 2113 uint32_t attachmentCount, 2114 const VkBool32 *pColorWriteEnables) 2115{ 2116 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 2117 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 2118 2119 assert(attachmentCount <= MESA_VK_MAX_COLOR_ATTACHMENTS); 2120 2121 uint8_t color_write_enables = 0; 2122 for (uint32_t a = 0; a < attachmentCount; a++) { 2123 if (pColorWriteEnables[a]) 2124 color_write_enables |= BITFIELD_BIT(a); 2125 } 2126 2127 SET_DYN_VALUE(dyn, CB_COLOR_WRITE_ENABLES, 2128 cb.color_write_enables, color_write_enables); 2129} 2130 2131VKAPI_ATTR void VKAPI_CALL 2132vk_common_CmdSetBlendConstants(VkCommandBuffer commandBuffer, 2133 const float blendConstants[4]) 2134{ 2135 VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer); 2136 struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state; 2137 2138 SET_DYN_ARRAY(dyn, CB_BLEND_CONSTANTS, cb.blend_constants, 2139 0, 4, blendConstants); 2140} 2141