1Graphics state 2============== 3 4The Mesa Vulkan runtime provides helpers for managing the numerous pieces 5of graphics state associated with a ``VkPipeline`` or set dynamically on a 6command buffer. No such helpers are provided for compute or ray-tracing 7because they have little or no state besides the shaders themselves. 8 9 10Pipeline state 11-------------- 12 13All (possibly dynamic) Vulkan graphics pipeline state is encapsulated into 14a single :c:struct:`vk_graphics_pipeline_state` structure which contains 15pointers to sub-structures for each of the different state categories. 16Unlike :c:type:`VkGraphicsPipelineCreateInfo`, the pointers in 17:c:struct:`vk_graphics_pipeline_state` are guaranteed to be either be 18NULL or point to valid and properly populated memory. 19 20When creating a pipeline, the 21:c:func:`vk_graphics_pipeline_state_fill()` function can be used to 22gather all of the state from the core structures as well as various ``pNext`` 23chains into a single state structure. Whenever an extension struct is 24missing, a reasonable default value is provided whenever possible. 25 26 27:c:func:`vk_graphics_pipeline_state_fill()` automatically handles both 28the render pass and dynamic rendering. For drivers which use 29:c:struct:`vk_render_pass`, the :c:struct:`vk_render_pass_state` 30structure will be populated as if for dynamic rendering, regardless of 31which path is used. Drivers which use their own render pass structure 32should parse the render pass, if available, and pass a 33:c:struct:`vk_render_pass_state` to the ``driver_rp`` argument of 34:c:func:`vk_graphics_pipeline_state_fill()` with the relevant information 35from the specified subpass. If a render pass is available, 36:c:struct:`vk_render_pass_state` will be populated with the 37the information from the :c:struct:`driver_rp`. If dynamic 38rendering is used or the driver provides a ``NULL`` 39:c:struct:`driver_rp`, the :c:struct:`vk_render_pass_state` 40structure will be populated for dynamic rendering, including color, depth, 41and stencil attachment formats. 42 43The usual flow for creating a full graphics pipeline (not library) looks 44like this: 45 46.. code-block:: c 47 48 struct vk_graphics_pipeline_state state = { }; 49 struct vk_graphics_pipeline_all_state all; 50 vk_graphics_pipeline_state_fill(&device->vk, &state, pCreateInfo, 51 NULL, &all, NULL, 0, NULL); 52 53 /* Emit stuff using the state in `state` */ 54 55The :c:struct:`vk_graphics_pipeline_all_state` structure exists to allow 56the state to sit on the stack instead of requiring a heap allocation. This 57is useful if you intend to use the state right away and don't need to store 58it. For pipeline libraries, it's likely more useful to use the dynamically 59allocated version and store the dynamically allocated memory in the 60library pipeline. 61 62.. code-block:: c 63 64 /* Assuming we have a vk_graphics_pipeline_state in pipeline */ 65 memset(&pipeline->state, 0, sizeof(pipeline->state)); 66 67 for (uint32_t i = 0; i < lib_info->libraryCount; i++) { 68 VK_FROM_HANDLE(drv_graphics_pipeline_library, lib, lib_info->pLibraries[i]); 69 vk_graphics_pipeline_state_merge(&pipeline->state, &lib->state); 70 } 71 72 /* This assumes you have a void **state_mem in pipeline */ 73 result = vk_graphics_pipeline_state_fill(&device->vk, &pipeline->state, 74 pCreateInfo, NULL, NULL, pAllocator, 75 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, 76 &pipeline->state_mem); 77 if (result != VK_SUCCESS) 78 return result; 79 80State from dependent libraries can be merged together using 81:c:func:`vk_graphics_pipeline_state_merge`. 82:c:func:`vk_graphics_pipeline_state_fill` will then only attempt to 83populate missing fields. You can also merge dependent pipeline libraries 84together but store the final state on the stack for immediate consumption: 85 86.. code-block:: c 87 88 struct vk_graphics_pipeline_state state = { }; 89 90 for (uint32_t i = 0; i < lib_info->libraryCount; i++) { 91 VK_FROM_HANDLE(drv_graphics_pipeline_library, lib, lib_info->pLibraries[i]); 92 vk_graphics_pipeline_state_merge(&state, &lib->state); 93 } 94 95 struct vk_graphics_pipeline_all_state all; 96 vk_graphics_pipeline_state_fill(&device->vk, &state, pCreateInfo, 97 NULL, &all, NULL, 0, NULL); 98 99.. c:autofunction:: vk_graphics_pipeline_state_fill 100 :file: src/vulkan/runtime/vk_graphics_state.h 101 102.. c:autofunction:: vk_graphics_pipeline_state_merge 103 :file: src/vulkan/runtime/vk_graphics_state.h 104 105 106Dynamic state 107------------- 108 109All dynamic states in Vulkan, regardless of which API version or extension 110introduced them, are represented by the 111:c:enum:`mesa_vk_dynamic_graphics_state` enum. This corresponds to the 112:c:type:`VkDynamicState` enum in the Vulkan API only it's compact (has no 113holes due to extension namespacing) and a bit better organized. Each 114enumerant is named with the name of the state group to which the dynamic 115state belongs as well as the name of the dynamic state itself. The fact 116that it's compact allows us to use to index bitsets. 117 118.. c:autofunction:: vk_get_dynamic_graphics_states 119 :file: src/vulkan/runtime/vk_graphics_state.h 120 121We also provide a :c:struct:`vk_dynamic_graphics_state` structure which 122contains all the dynamic graphics states, regardless of which API version 123or extension introduced them. This structure can be populated from a 124:c:struct:`vk_graphics_pipeline_state` via 125:c:func:`vk_dynamic_graphics_state_init`. 126 127.. c:autofunction:: vk_dynamic_graphics_state_init 128 :file: src/vulkan/runtime/vk_graphics_state.h 129 130.. c:autofunction:: vk_dynamic_graphics_state_copy 131 :file: src/vulkan/runtime/vk_graphics_state.h 132 133There is also a :c:struct:`vk_dynamic_graphics_state` embedded in 134:c:struct:`vk_command_buffer`. Should you choose to use them, we provide 135common implementations for all ``vkCmdSet*()`` functions. Two additional 136functions are provided for the driver to call in ``CmdBindPipeline()`` and 137``CmdBindVertexBuffers2()``: 138 139.. c:autofunction:: vk_cmd_set_dynamic_graphics_state 140 :file: src/vulkan/runtime/vk_graphics_state.h 141 142.. c:autofunction:: vk_cmd_set_vertex_binding_strides 143 :file: src/vulkan/runtime/vk_graphics_state.h 144 145To use the dynamic state framework, you will need the following in your 146pipeline structure: 147 148.. code-block:: c 149 150 struct drv_graphics_pipeline { 151 .... 152 struct vk_vertex_input_state vi_state; 153 struct vk_sample_locations_state sl_state; 154 struct vk_dynamic_graphics_state dynamic; 155 ... 156 }; 157 158Then, in your pipeline create function, 159 160.. code-block:: c 161 162 memset(&pipeline->dynamic, 0, sizeof(pipeline->dynamic)); 163 pipeline->dynamic->vi = &pipeline->vi_state; 164 pipeline->dynamic->ms.sample_locations = &pipeline->sl_state; 165 vk_dynamic_graphics_state_init(&pipeline->dynamic, &state); 166 167In your implementation of ``vkCmdBindPipeline()``, 168 169.. code-block:: c 170 171 vk_cmd_set_dynamic_graphics_state(&cmd->vk, &pipeline->dynamic_state); 172 173And, finally, at ``vkCmdDraw*()`` time, the code to emit dynamic state into 174your hardware command buffer will look something like this: 175 176.. code-block:: c 177 178 static void 179 emit_dynamic_state(struct drv_cmd_buffer *cmd) 180 { 181 struct vk_dynamic_graphics_state *dyn = &cmd->vk.dynamic_graphics_state; 182 183 if (!vk_dynamic_graphics_state_any_dirty(dyn)) 184 return; 185 186 if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORTS) | 187 BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT)) { 188 /* Re-emit viewports */ 189 } 190 191 if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_SCISSORS) | 192 BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_VP_SCISSOR_COUNT)) { 193 /* Re-emit scissors */ 194 } 195 196 /* etc... */ 197 198 vk_dynamic_graphics_state_clear_dirty(dyn); 199 } 200 201Any states used by the currently bound pipeline and attachments are always 202valid in ``vk_command_buffer::dynamic_graphics_state`` so you can always 203use a state even if it isn't dirty on this particular draw. 204 205.. c:autofunction:: vk_dynamic_graphics_state_dirty_all 206 :file: src/vulkan/runtime/vk_graphics_state.h 207 208.. c:autofunction:: vk_dynamic_graphics_state_clear_dirty 209 :file: src/vulkan/runtime/vk_graphics_state.h 210 211.. c:autofunction:: vk_dynamic_graphics_state_any_dirty 212 :file: src/vulkan/runtime/vk_graphics_state.h 213 214 215Depth stencil state optimization 216-------------------------------- 217 218.. c:autofunction:: vk_optimize_depth_stencil_state 219 :file: src/vulkan/runtime/vk_graphics_state.h 220 221 222Reference 223--------- 224 225.. c:autostruct:: vk_graphics_pipeline_state 226 :file: src/vulkan/runtime/vk_graphics_state.h 227 :members: 228 229.. c:autostruct:: vk_vertex_binding_state 230 :file: src/vulkan/runtime/vk_graphics_state.h 231 :members: 232 233.. c:autostruct:: vk_vertex_attribute_state 234 :file: src/vulkan/runtime/vk_graphics_state.h 235 :members: 236 237.. c:autostruct:: vk_vertex_input_state 238 :file: src/vulkan/runtime/vk_graphics_state.h 239 :members: 240 241.. c:autostruct:: vk_input_assembly_state 242 :file: src/vulkan/runtime/vk_graphics_state.h 243 :members: 244 245.. c:autostruct:: vk_tessellation_state 246 :file: src/vulkan/runtime/vk_graphics_state.h 247 :members: 248 249.. c:autostruct:: vk_viewport_state 250 :file: src/vulkan/runtime/vk_graphics_state.h 251 :members: 252 253.. c:autostruct:: vk_discard_rectangles_state 254 :file: src/vulkan/runtime/vk_graphics_state.h 255 :members: 256 257.. c:autostruct:: vk_rasterization_state 258 :file: src/vulkan/runtime/vk_graphics_state.h 259 :members: 260 261.. c:autostruct:: vk_fragment_shading_rate_state 262 :file: src/vulkan/runtime/vk_graphics_state.h 263 :members: 264 265.. c:autostruct:: vk_sample_locations_state 266 :file: src/vulkan/runtime/vk_graphics_state.h 267 :members: 268 269.. c:autostruct:: vk_multisample_state 270 :file: src/vulkan/runtime/vk_graphics_state.h 271 :members: 272 273.. c:autostruct:: vk_stencil_test_face_state 274 :file: src/vulkan/runtime/vk_graphics_state.h 275 :members: 276 277.. c:autostruct:: vk_depth_stencil_state 278 :file: src/vulkan/runtime/vk_graphics_state.h 279 :members: 280 281.. c:autostruct:: vk_color_blend_state 282 :file: src/vulkan/runtime/vk_graphics_state.h 283 :members: 284 285.. c:autostruct:: vk_render_pass_state 286 :file: src/vulkan/runtime/vk_graphics_state.h 287 :members: 288 289.. c:autoenum:: mesa_vk_dynamic_graphics_state 290 :file: src/vulkan/runtime/vk_graphics_state.h 291 292.. c:autostruct:: vk_dynamic_graphics_state 293 :file: src/vulkan/runtime/vk_graphics_state.h 294 :members: 295