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