1ANV 2=== 3 4Debugging 5--------- 6 7Here are a few environment variable debug environment variables 8specific to Anv: 9 10:envvar:`ANV_ENABLE_PIPELINE_CACHE` 11 If defined to ``0`` or ``false``, this will disable pipeline 12 caching, forcing Anv to reparse and recompile any VkShaderModule 13 (SPIRV) it is given. 14:envvar:`ANV_DISABLE_SECONDARY_CMD_BUFFER_CALLS` 15 If defined to ``1`` or ``true``, this will prevent usage of self 16 modifying command buffers to implement ``vkCmdExecuteCommands``. As 17 a result of this, it will also disable ``VK_KHR_performance_query``. 18:envvar:`ANV_ALWAYS_BINDLESS` 19 If defined to ``1`` or ``true``, this forces all descriptor sets to 20 use the internal `Bindless model`_. 21:envvar:`ANV_QUEUE_THREAD_DISABLE` 22 If defined to ``1`` or ``true``, this disables support for timeline 23 semaphores. 24:envvar:`ANV_USERSPACE_RELOCS` 25 If defined to ``1`` or ``true``, this forces Anv to always do 26 kernel relocations in command buffers. This should only have an 27 effect on hardware that doesn't support soft-pinning (Ivybridge, 28 Haswell, Cherryview). 29:envvar:`ANV_PRIMITIVE_REPLICATION_MAX_VIEWS` 30 Specifies up to how many view shaders can be lowered to handle 31 VK_KHR_multiview. Beyond this number, multiview is implemented 32 using instanced rendering. If unspecified, the value default to 33 ``2``. 34 35 36Experimental features 37--------------------- 38 39:envvar:`ANV_EXPERIMENTAL_NV_MESH_SHADER` 40 If defined to ``1`` or ``true``, this advertise support for 41 VK_NV_mesh_shader extension for platforms that have hardware 42 support for it. 43 44 45.. _`Bindless model`: 46 47Binding Model 48------------- 49 50Here is the Anv bindless binding model that was implemented for the 51descriptor indexing feature of Vulkan 1.2 : 52 53.. graphviz:: 54 55 digraph G { 56 fontcolor="black"; 57 compound=true; 58 59 subgraph cluster_1 { 60 label = "Binding Table (HW)"; 61 62 bgcolor="cornflowerblue"; 63 64 node [ style=filled,shape="record",fillcolor="white", 65 label="RT0" ] n0; 66 node [ label="RT1" ] n1; 67 node [ label="dynbuf0"] n2; 68 node [ label="set0" ] n3; 69 node [ label="set1" ] n4; 70 node [ label="set2" ] n5; 71 72 n0 -> n1 -> n2 -> n3 -> n4 -> n5 [style=invis]; 73 } 74 subgraph cluster_2 { 75 label = "Descriptor Set 0"; 76 77 bgcolor="burlywood3"; 78 fixedsize = true; 79 80 node [ style=filled,shape="record",fillcolor="white", fixedsize = true, width=4, 81 label="binding 0 - STORAGE_IMAGE\n anv_storage_image_descriptor" ] n8; 82 node [ label="binding 1 - COMBINED_IMAGE_SAMPLER\n anv_sampled_image_descriptor" ] n9; 83 node [ label="binding 2 - UNIFORM_BUFFER\n anv_address_range_descriptor" ] n10; 84 node [ label="binding 3 - UNIFORM_TEXEL_BUFFER\n anv_storage_image_descriptor" ] n11; 85 86 n8 -> n9 -> n10 -> n11 [style=invis]; 87 } 88 subgraph cluster_5 { 89 label = "Vulkan Objects" 90 91 fontcolor="black"; 92 bgcolor="darkolivegreen4"; 93 94 subgraph cluster_6 { 95 label = "VkImageView"; 96 97 bgcolor=darkolivegreen3; 98 node [ style=filled,shape="box",fillcolor="white", fixedsize = true, width=2, 99 label="surface_state" ] n12; 100 } 101 subgraph cluster_7 { 102 label = "VkSampler"; 103 104 bgcolor=darkolivegreen3; 105 node [ style=filled,shape="box",fillcolor="white", fixedsize = true, width=2, 106 label="sample_state" ] n13; 107 } 108 subgraph cluster_8 { 109 label = "VkImageView"; 110 bgcolor="darkolivegreen3"; 111 112 node [ style=filled,shape="box",fillcolor="white", fixedsize = true, width=2, 113 label="surface_state" ] n14; 114 } 115 subgraph cluster_9 { 116 label = "VkBuffer"; 117 bgcolor=darkolivegreen3; 118 119 node [ style=filled,shape="box",fillcolor="white", fixedsize = true, width=2, 120 label="address" ] n15; 121 } 122 subgraph cluster_10 { 123 label = "VkBufferView"; 124 125 bgcolor=darkolivegreen3; 126 node [ style=filled,shape="box",fillcolor="white", fixedsize = true, width=2, 127 label="surface_state" ] n16; 128 } 129 130 n12 -> n13 -> n14 -> n15 -> n16 [style=invis]; 131 } 132 133 subgraph cluster_11 { 134 subgraph cluster_12 { 135 label = "CommandBuffer state stream"; 136 137 bgcolor="gold3"; 138 node [ style=filled,shape="box",fillcolor="white", fixedsize = true, width=2, 139 label="surface_state" ] n17; 140 node [ label="surface_state" ] n18; 141 node [ label="surface_state" ] n19; 142 143 n17 -> n18 -> n19 [style=invis]; 144 } 145 } 146 147 n3 -> n8 [lhead=cluster_2]; 148 149 n8 -> n12; 150 n9 -> n13; 151 n9 -> n14; 152 n10 -> n15; 153 n11 -> n16; 154 155 n0 -> n17; 156 n1 -> n18; 157 n2 -> n19; 158 } 159 160 161 162The HW binding table is generated when the draw or dispatch commands 163are emitted. Here are the types of entries one can find in the binding 164table : 165 166- The currently bound descriptor sets, one entry per descriptor set 167 (our limit is 8). 168 169- For dynamic buffers, one entry per dynamic buffer. 170 171- For draw commands, render target entries if needed. 172 173The entries of the HW binding table for descriptor sets are 174RENDER_SURFACE_STATE similar to what you would have for a normal 175uniform buffer. The shader will emit reads this buffer first to get 176the information it needs to access a surface/sampler/etc... and then 177emits the appropriate message using the information gathered from the 178descriptor set buffer. 179 180Each binding type entry gets an associated structure in memory 181(``anv_storage_image_descriptor``, ``anv_sampled_image_descriptor``, 182``anv_address_range_descriptor``, ``anv_storage_image_descriptor``). 183This is the information read by the shader. 184 185 186.. _`Descriptor Set Memory Layout`: 187 188Descriptor Set Memory Layout 189---------------------------- 190 191Here is a representation of how the descriptor set bindings, with each 192elements in each binding is mapped to a the descriptor set memory : 193 194.. graphviz:: 195 196 digraph structs { 197 node [shape=record]; 198 rankdir=LR; 199 200 struct1 [label="Descriptor Set | \ 201 <b0> binding 0\n STORAGE_IMAGE \n (array_length=3) | \ 202 <b1> binding 1\n COMBINED_IMAGE_SAMPLER \n (array_length=2) | \ 203 <b2> binding 2\n UNIFORM_BUFFER \n (array_length=1) | \ 204 <b3> binding 3\n UNIFORM_TEXEL_BUFFER \n (array_length=1)"]; 205 struct2 [label="Descriptor Set Memory | \ 206 <b0e0> anv_storage_image_descriptor|\ 207 <b0e1> anv_storage_image_descriptor|\ 208 <b0e2> anv_storage_image_descriptor|\ 209 <b1e0> anv_sampled_image_descriptor|\ 210 <b1e1> anv_sampled_image_descriptor|\ 211 <b2e0> anv_address_range_descriptor|\ 212 <b3e0> anv_storage_image_descriptor"]; 213 214 struct1:b0 -> struct2:b0e0; 215 struct1:b0 -> struct2:b0e1; 216 struct1:b0 -> struct2:b0e2; 217 struct1:b1 -> struct2:b1e0; 218 struct1:b1 -> struct2:b1e1; 219 struct1:b2 -> struct2:b2e0; 220 struct1:b3 -> struct2:b3e0; 221 } 222 223Each Binding in the descriptor set is allocated an array of 224``anv_*_descriptor`` data structure. The type of ``anv_*_descriptor`` 225used for a binding is selected based on the ``VkDescriptorType`` of 226the bindings. 227 228The value of ``anv_descriptor_set_binding_layout::descriptor_offset`` 229is a byte offset from the descriptor set memory to the associated 230binding. ``anv_descriptor_set_binding_layout::array_size`` is the 231number of ``anv_*_descriptor`` elements in the descriptor set memory 232from that offset for the binding. 233 234 235Pipeline state emission 236----------------------- 237 238Vulkan initially started by baking as much state as possible in 239pipelines. But extension after extension, more and more state has 240become potentially dynamic. 241 242Anv tries to limit the amount of time an instruction has to be packed 243to reprogram part of the 3D pipeline state. The packing is happening 244in 2 places : 245 246- ``genX_pipeline.c`` where the non dynamic state is emitted in the 247 pipeline batch. This batch is copied into the command buffer batch 248 when calling ``vkCmdBindPipeline()`` 249 250- ``genX_cmd_buffer.c`` in the ``cmd_buffer_flush_state`` function 251 which ends up calling into ``gfx8_cmd_buffer.c`` & 252 ``gfx7_cmd_buffer.c`` 253 254The rule to know where to emit an instruction programming the 3D 255pipeline is as follow : 256 257- If any field of the instruction can be made dynamic, it should be 258 emitted in ``genX_cmd_buffer.c``, ``gfx8_cmd_buffer.c`` or 259 ``gfx7_cmd_buffer.c`` 260 261- Otherwise, the instruction can be emitted in ``genX_pipeline.c`` 262 263When a piece of state programming is dynamic, it should have a 264corresponding field in ``anv_dynamic_state`` and the 265``anv_dynamic_state_copy()`` function should be updated to ensure we 266minimize the amount of time an instruction should be emitted. Each 267instruction should have a associated ``ANV_CMD_DIRTY_*`` mask so that 268the dynamic emission code can tell when to re-emit an instruction. 269 270An instruction can also be re-emitted when a pipeline changes by 271checking for ``ANV_CMD_DIRTY_PIPELINE``. It should only do so if it 272requires to know some value that is coming from the 273``anv_graphics_pipeline`` object that is not available from 274``anv_dynamic_state``. 275