/* * Copyright © 2022 Collabora, Ltd * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef VK_GRAPHICS_STATE_H #define VK_GRAPHICS_STATE_H #include "vulkan/vulkan_core.h" #include "vk_limits.h" #include "util/bitset.h" #ifdef __cplusplus extern "C" { #endif struct vk_command_buffer; struct vk_device; /** Enumeration of all Vulkan dynamic graphics states * * Enumerants are named with both the abreviation of the state group to which * the state belongs as well as the name of the state itself. These are * intended to pretty closely match the VkDynamicState enum but may not match * perfectly all the time. */ enum mesa_vk_dynamic_graphics_state { MESA_VK_DYNAMIC_VI, MESA_VK_DYNAMIC_VI_BINDING_STRIDES, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS, MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT, MESA_VK_DYNAMIC_VP_VIEWPORTS, MESA_VK_DYNAMIC_VP_SCISSOR_COUNT, MESA_VK_DYNAMIC_VP_SCISSORS, MESA_VK_DYNAMIC_DR_RECTANGLES, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE, MESA_VK_DYNAMIC_RS_CULL_MODE, MESA_VK_DYNAMIC_RS_FRONT_FACE, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS, MESA_VK_DYNAMIC_RS_LINE_WIDTH, MESA_VK_DYNAMIC_RS_LINE_STIPPLE, MESA_VK_DYNAMIC_FSR, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE, MESA_VK_DYNAMIC_DS_STENCIL_OP, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE, MESA_VK_DYNAMIC_CB_LOGIC_OP, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS, /* Must be left at the end */ MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX, }; /** Populate a bitset with dynamic states * * This function maps a VkPipelineDynamicStateCreateInfo to a bitset indexed * by mesa_vk_dynamic_graphics_state enumerants. * * @param[out] dynamic Bitset to populate * @param[in] info VkPipelineDynamicStateCreateInfo or NULL */ void vk_get_dynamic_graphics_states(BITSET_WORD *dynamic, const VkPipelineDynamicStateCreateInfo *info); struct vk_vertex_binding_state { /** VkVertexInputBindingDescription::stride */ uint16_t stride; /** VkVertexInputBindingDescription::inputRate */ uint16_t input_rate; /** VkVertexInputBindingDivisorDescriptionEXT::divisor or 1 */ uint32_t divisor; }; struct vk_vertex_attribute_state { /** VkVertexInputAttributeDescription::binding */ uint32_t binding; /** VkVertexInputAttributeDescription::format */ VkFormat format; /** VkVertexInputAttributeDescription::offset */ uint32_t offset; }; struct vk_vertex_input_state { /** Bitset of which bindings are valid, indexed by binding */ uint32_t bindings_valid; struct vk_vertex_binding_state bindings[MESA_VK_MAX_VERTEX_BINDINGS]; /** Bitset of which attributes are valid, indexed by location */ uint32_t attributes_valid; struct vk_vertex_attribute_state attributes[MESA_VK_MAX_VERTEX_ATTRIBUTES]; }; struct vk_input_assembly_state { /** VkPipelineInputAssemblyStateCreateInfo::topology * * MESA_VK_DYNAMIC_GRAPHICS_STATE_IA_PRIMITIVE_TOPOLOGY */ uint8_t primitive_topology; /** VkPipelineInputAssemblyStateCreateInfo::primitiveRestartEnable * * MESA_VK_DYNAMIC_GRAPHICS_STATE_IA_PRIMITIVE_RESTART_ENABLE */ bool primitive_restart_enable; }; struct vk_tessellation_state { /** VkPipelineTessellationStateCreateInfo::patchControlPoints */ uint8_t patch_control_points; /** VkPipelineTessellationDomainOriginStateCreateInfo::domainOrigin */ uint8_t domain_origin; }; struct vk_viewport_state { /** VkPipelineViewportDepthClipControlCreateInfoEXT::negativeOneToOne */ bool negative_one_to_one; /** VkPipelineViewportStateCreateInfo::viewportCount */ uint8_t viewport_count; /** VkPipelineViewportStateCreateInfo::scissorCount */ uint8_t scissor_count; /** VkPipelineViewportStateCreateInfo::pViewports */ VkRect2D scissors[MESA_VK_MAX_SCISSORS]; /** VkPipelineViewportStateCreateInfo::pScissors */ VkViewport viewports[MESA_VK_MAX_VIEWPORTS]; }; struct vk_discard_rectangles_state { /** VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleMode */ VkDiscardRectangleModeEXT mode; /** VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleCount */ uint32_t rectangle_count; /** VkPipelineDiscardRectangleStateCreateInfoEXT::pDiscardRectangles */ VkRect2D rectangles[MESA_VK_MAX_DISCARD_RECTANGLES]; }; struct vk_rasterization_state { /** VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable * * This will be false if rasterizer discard is dynamic */ bool rasterizer_discard_enable; /** VkPipelineRasterizationStateCreateInfo::depthClampEnable */ bool depth_clamp_enable; /** VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnable */ bool depth_clip_enable; /** VkPipelineRasterizationStateCreateInfo::polygonMode */ VkPolygonMode polygon_mode; /** VkPipelineRasterizationStateCreateInfo::cullMode */ VkCullModeFlags cull_mode; /** VkPipelineRasterizationStateCreateInfo::frontFace */ VkFrontFace front_face; /** VkPipelineRasterizationConservativeStateCreateInfoEXT::conservativeRasterizationMode */ VkConservativeRasterizationModeEXT conservative_mode; /** VkPipelineRasterizationStateRasterizationOrderAMD::rasterizationOrder */ VkRasterizationOrderAMD rasterization_order_amd; /** VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::provokingVertexMode */ VkProvokingVertexModeEXT provoking_vertex; /** VkPipelineRasterizationStateStreamCreateInfoEXT::rasterizationStream */ uint32_t rasterization_stream; struct { /** VkPipelineRasterizationStateCreateInfo::depthBiasEnable */ bool enable; /** VkPipelineRasterizationStateCreateInfo::depthBiasConstantFactor */ float constant; /** VkPipelineRasterizationStateCreateInfo::depthBiasClamp */ float clamp; /** VkPipelineRasterizationStateCreateInfo::depthBiasSlopeFactor */ float slope; } depth_bias; struct { /** VkPipelineRasterizationStateCreateInfo::lineWidth */ float width; /** VkPipelineRasterizationLineStateCreateInfoEXT::lineRasterizationMode * * Will be set to VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT if * VkPipelineRasterizationLineStateCreateInfoEXT is not provided. */ VkLineRasterizationModeEXT mode; struct { /** VkPipelineRasterizationLineStateCreateInfoEXT::stippledLineEnable */ bool enable; /** VkPipelineRasterizationLineStateCreateInfoEXT::lineStippleFactor */ uint32_t factor; /** VkPipelineRasterizationLineStateCreateInfoEXT::lineStipplePattern */ uint16_t pattern; } stipple; } line; }; struct vk_fragment_shading_rate_state { /** VkPipelineFragmentShadingRateStateCreateInfoKHR::fragmentSize * * MESA_VK_DYNAMIC_GRAPHICS_STATE_FSR */ VkExtent2D fragment_size; /** VkPipelineFragmentShadingRateStateCreateInfoKHR::combinerOps * * MESA_VK_DYNAMIC_GRAPHICS_STATE_FSR */ VkFragmentShadingRateCombinerOpKHR combiner_ops[2]; }; struct vk_sample_locations_state { /** VkSampleLocationsInfoEXT::sampleLocationsPerPixel */ VkSampleCountFlagBits per_pixel; /** VkSampleLocationsInfoEXT::sampleLocationGridSize */ VkExtent2D grid_size; /** VkSampleLocationsInfoEXT::sampleLocations */ VkSampleLocationEXT locations[MESA_VK_MAX_SAMPLE_LOCATIONS]; }; struct vk_multisample_state { /** VkPipelineMultisampleStateCreateInfo::rasterizationSamples */ VkSampleCountFlagBits rasterization_samples; /** VkPipelineMultisampleStateCreateInfo::sampleShadingEnable */ bool sample_shading_enable; /** VkPipelineMultisampleStateCreateInfo::minSampleShading */ float min_sample_shading; /** VkPipelineMultisampleStateCreateInfo::pSampleMask */ uint16_t sample_mask; /** VkPipelineMultisampleStateCreateInfo::alphaToCoverageEnable */ bool alpha_to_coverage_enable; /** VkPipelineMultisampleStateCreateInfo::alphaToOneEnable */ bool alpha_to_one_enable; /** VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsEnable */ bool sample_locations_enable; /** VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsInfo * * May be NULL for dynamic sample locations. */ const struct vk_sample_locations_state *sample_locations; }; /** Represents the stencil test state for a face */ struct vk_stencil_test_face_state { /* * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_OP */ struct { /** VkStencilOpState::failOp */ uint8_t fail; /** VkStencilOpState::passOp */ uint8_t pass; /** VkStencilOpState::depthFailOp */ uint8_t depth_fail; /** VkStencilOpState::compareOp */ uint8_t compare; } op; /** VkStencilOpState::compareMask * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_COMPARE_MASK */ uint8_t compare_mask; /** VkStencilOpState::writeMask * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_WRITE_MASK */ uint8_t write_mask; /** VkStencilOpState::reference * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_REFERENCE */ uint8_t reference; }; struct vk_depth_stencil_state { struct { /** VkPipelineDepthStencilStateCreateInfo::depthTestEnable * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_TEST_ENABLE */ bool test_enable; /** VkPipelineDepthStencilStateCreateInfo::depthWriteEnable * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_WRITE_ENABLE */ bool write_enable; /** VkPipelineDepthStencilStateCreateInfo::depthCompareOp * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_COMPARE_OP */ VkCompareOp compare_op; struct { /** VkPipelineDepthStencilStateCreateInfo::depthBoundsTestEnable * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_BOUNDS_TEST_ENABLE */ bool enable; /** VkPipelineDepthStencilStateCreateInfo::min/maxDepthBounds * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_DEPTH_BOUNDS_TEST_BOUNDS */ float min, max; } bounds_test; } depth; struct { /** VkPipelineDepthStencilStateCreateInfo::stencilTestEnable * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DS_STENCIL_TEST_ENABLE */ bool test_enable; /** Whether or not stencil is should be written * * This does not map directly to any particular Vulkan API state and is * initialized to true. If independent stencil disable ever becomes a * thing, it will use this state. vk_optimize_depth_stencil_state() may * set this to false if it can prove that the stencil test will never * alter the stencil value. */ bool write_enable; /** VkPipelineDepthStencilStateCreateInfo::front */ struct vk_stencil_test_face_state front; /** VkPipelineDepthStencilStateCreateInfo::back */ struct vk_stencil_test_face_state back; } stencil; }; /** Optimize a depth/stencil state * * The way depth and stencil testing is specified, there are many case where, * regardless of depth/stencil writes being enabled, nothing actually gets * written due to some other bit of state being set. In the presence of * discards, it's fairly easy to get into cases where early depth/stencil * testing is disabled on some hardware, leading to a fairly big performance * hit. This function attempts to optimize the depth stencil state and * disable writes and sometimes even testing whenever possible. * * @param[inout] ds The depth stencil state to optimize * @param[in] ds_aspects Which image aspects are present in the render * pass. */ void vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds, VkImageAspectFlags ds_aspects); struct vk_color_blend_attachment_state { /** VkPipelineColorBlendAttachmentState::blendEnable */ bool blend_enable; /** VkPipelineColorBlendAttachmentState::srcColorBlendFactor */ uint8_t src_color_blend_factor; /** VkPipelineColorBlendAttachmentState::dstColorBlendFactor */ uint8_t dst_color_blend_factor; /** VkPipelineColorBlendAttachmentState::srcAlphaBlendFactor */ uint8_t src_alpha_blend_factor; /** VkPipelineColorBlendAttachmentState::dstAlphaBlendFactor */ uint8_t dst_alpha_blend_factor; /** VkPipelineColorBlendAttachmentState::colorWriteMask */ uint8_t write_mask; /** VkPipelineColorBlendAttachmentState::colorBlendOp */ VkBlendOp color_blend_op; /** VkPipelineColorBlendAttachmentState::alphaBlendOp */ VkBlendOp alpha_blend_op; }; struct vk_color_blend_state { /** VkPipelineColorBlendStateCreateInfo::logicOpEnable */ bool logic_op_enable; /** VkPipelineColorBlendStateCreateInfo::logicOp */ uint8_t logic_op; /** VkPipelineColorWriteCreateInfoEXT::pColorWriteEnables */ uint8_t color_write_enables; /** VkPipelineColorBlendStateCreateInfo::attachmentCount */ uint8_t attachment_count; /** VkPipelineColorBlendStateCreateInfo::pAttachments */ struct vk_color_blend_attachment_state attachments[MESA_VK_MAX_COLOR_ATTACHMENTS]; /** VkPipelineColorBlendStateCreateInfo::blendConstants */ float blend_constants[4]; }; struct vk_render_pass_state { /** Set of image aspects bound as color/depth/stencil attachments * * Set to VK_IMAGE_ASPECT_METADATA_BIT to indicate that attachment info * is invalid. */ VkImageAspectFlags attachment_aspects; /** VkGraphicsPipelineCreateInfo::renderPass */ VkRenderPass render_pass; /** VkGraphicsPipelineCreateInfo::subpass */ uint32_t subpass; /** VkPipelineRenderingCreateInfo::viewMask */ uint32_t view_mask; /** VkRenderingSelfDependencyInfoMESA::colorSelfDependencies */ uint8_t color_self_dependencies; /** VkRenderingSelfDependencyInfoMESA::depthSelfDependency */ bool depth_self_dependency; /** VkRenderingSelfDependencyInfoMESA::stencilSelfDependency */ bool stencil_self_dependency; /** VkPipelineRenderingCreateInfo::colorAttachmentCount */ uint8_t color_attachment_count; /** VkPipelineRenderingCreateInfo::pColorAttachmentFormats */ VkFormat color_attachment_formats[MESA_VK_MAX_COLOR_ATTACHMENTS]; /** VkPipelineRenderingCreateInfo::depthAttachmentFormat */ VkFormat depth_attachment_format; /** VkPipelineRenderingCreateInfo::stencilAttachmentFormat */ VkFormat stencil_attachment_format; }; /** Struct representing all dynamic graphics state * * Before invoking any core functions, the driver must properly populate * initialize this struct: * * - Initialize using vk_default_dynamic_graphics_state, if desired * - Set vi to a driver-allocated vk_vertex_input_state struct * - Set ms.sample_locations to a driver-allocated * vk_sample_locations_state struct */ struct vk_dynamic_graphics_state { /** Vertex input state * * Must be provided by the driver if VK_EXT_vertex_input_dynamic_state is * supported. * * MESA_VK_DYNAMIC_GRAPHICS_STATE_VI */ struct vk_vertex_input_state *vi; /** Vertex binding strides * * MESA_VK_DYNAMIC_GRAPHICS_STATE_VI_BINDING_STRIDES */ uint16_t vi_binding_strides[MESA_VK_MAX_VERTEX_BINDINGS]; struct vk_input_assembly_state ia; struct { uint32_t patch_control_points; } ts; /** Viewport state */ struct { /** Viewport count * * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_VIEWPORT_COUNT */ uint32_t viewport_count; /** Viewports * * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_VIEWPORTS */ VkViewport viewports[MESA_VK_MAX_VIEWPORTS]; /** Scissor count * * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_SCISSOR_COUNT */ uint32_t scissor_count; /** Scissor rects * * MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_SCISSORS */ VkRect2D scissors[MESA_VK_MAX_SCISSORS]; } vp; /** Discard rectangles * * MESA_VK_DYNAMIC_GRAPHICS_STATE_DR_RECTANGLES */ struct { uint32_t rectangle_count; VkRect2D rectangles[MESA_VK_MAX_DISCARD_RECTANGLES]; } dr; /** Rasterization state */ struct { /** Rasterizer discard * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_RASTERIZER_DISCARD_ENABLE */ bool rasterizer_discard_enable; /** Cull mode * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_CULL_MODE */ VkCullModeFlags cull_mode; /** Front face * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_FRONT_FACE */ VkFrontFace front_face; struct { /** Depth bias enable * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_DEPTH_BIAS_ENABLE */ bool enable; /** Depth bias constant factor * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_DEPTH_BIAS_FACTORS */ float constant; /** Depth bias clamp * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_DEPTH_BIAS_FACTORS */ float clamp; /** Depth bias slope * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_DEPTH_BIAS_FACTORS */ float slope; } depth_bias; struct { /** Line width * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_LINE_WIDTH */ float width; /** Line stipple * * MESA_VK_DYNAMIC_GRAPHICS_STATE_RS_LINE_STIPPLE */ struct { uint32_t factor; uint16_t pattern; } stipple; } line; } rs; struct vk_fragment_shading_rate_state fsr; /** Multisample state */ struct { /** Sample locations * * Must be provided by the driver if VK_EXT_sample_locations is * supported. * * MESA_VK_DYNAMIC_GRAPHICS_STATE_MS_SAMPLE_LOCATIONS */ struct vk_sample_locations_state *sample_locations; } ms; struct vk_depth_stencil_state ds; /** Color blend state */ struct { /** Integer color logic op * * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_LOGIC_OP, */ VkLogicOp logic_op; /** Color write enables * * Bitmask of color write enables, indexed by color attachment index. * * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_COLOR_WRITE_ENABLES, */ uint32_t color_write_enables; /** Blend constants * * MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_BLEND_CONSTANTS, */ float blend_constants[4]; } cb; /** For pipelines, which bits of dynamic state are set */ BITSET_DECLARE(set, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); /** For command buffers, which bits of dynamic state have changed */ BITSET_DECLARE(dirty, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); }; struct vk_graphics_pipeline_all_state { struct vk_vertex_input_state vi; struct vk_input_assembly_state ia; struct vk_tessellation_state ts; struct vk_viewport_state vp; struct vk_discard_rectangles_state dr; struct vk_rasterization_state rs; struct vk_fragment_shading_rate_state fsr; struct vk_multisample_state ms; struct vk_sample_locations_state ms_sample_locations; struct vk_depth_stencil_state ds; struct vk_color_blend_state cb; struct vk_render_pass_state rp; }; struct vk_graphics_pipeline_state { /** Bitset of which states are dynamic */ BITSET_DECLARE(dynamic, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX); /** Vertex input state */ const struct vk_vertex_input_state *vi; /** Input assembly state */ const struct vk_input_assembly_state *ia; /** Tessellation state */ const struct vk_tessellation_state *ts; /** Viewport state */ const struct vk_viewport_state *vp; /** Discard Rectangles state */ const struct vk_discard_rectangles_state *dr; /** Rasterization state */ const struct vk_rasterization_state *rs; /** Fragment shading rate state */ const struct vk_fragment_shading_rate_state *fsr; /** Multiesample state */ const struct vk_multisample_state *ms; /** Depth stencil state */ const struct vk_depth_stencil_state *ds; /** Color blend state */ const struct vk_color_blend_state *cb; /** Render pass state */ const struct vk_render_pass_state *rp; }; /** Struct for extra information that we need from the subpass. * * This struct need only be provided if the driver has its own render pass * implementation. If the driver uses the common render pass implementation, * we can get this information ourselves. */ struct vk_subpass_info { uint32_t view_mask; VkImageAspectFlags attachment_aspects; }; /** Populate a vk_graphics_pipeline_state from VkGraphicsPipelineCreateInfo * * This function crawls the provided VkGraphicsPipelineCreateInfo and uses it * to populate the vk_graphics_pipeline_state. Upon returning from this * function, all pointers in `state` will either be `NULL` or point to a valid * sub-state structure. Whenever an extension struct is missing, a reasonable * default value is provided whenever possible. Some states may be left NULL * if the state does not exist (such as when rasterizer discard is enabled) or * if all of the corresponding states are dynamic. * * This function assumes that the vk_graphics_pipeline_state is already valid * (i.e., all pointers are NULL or point to valid states). Any states already * present are assumed to be identical to how we would populate them from * VkGraphicsPipelineCreateInfo. * * This function can operate in one of two modes with respect to how the * memory for states is allocated. If a `vk_graphics_pipeline_all_state` * struct is provided, any newly populated states will point to the relevant * field in `all`. If `all == NULL`, it attempts to dynamically allocate any * newly required states using the provided allocator and scope. The pointer * to this new blob of memory is returned via `alloc_ptr_out` and must * eventually be freed by the driver. * * @param[in] device The Vulkan device * @param[out] state The graphics pipeline state to populate * @param[in] info The pCreateInfo from vkCreateGraphicsPipelines * @param[in] sp_info Subpass info if the driver implements render * passes itself. This should be NULL for drivers * that use the common render pass infrastructure * built on top of dynamic rendering. * @param[in] all The vk_graphics_pipeline_all_state to use to * back any newly needed states. If NULL, newly * needed states will be dynamically allocated * instead. * @param[in] alloc Allocation callbacks for dynamically allocating * new state memory. * @param[in] scope Allocation scope for dynamically allocating new * state memory. * @param[out] alloc_ptr_out Will be populated with a pointer to any newly * allocated state. The driver is responsible for * freeing this pointer. */ VkResult vk_graphics_pipeline_state_fill(const struct vk_device *device, struct vk_graphics_pipeline_state *state, const VkGraphicsPipelineCreateInfo *info, const struct vk_subpass_info *sp_info, struct vk_graphics_pipeline_all_state *all, const VkAllocationCallbacks *alloc, VkSystemAllocationScope scope, void **alloc_ptr_out); /** Merge one vk_graphics_pipeline_state into another * * Both the destination and source states are assumed to be valid (i.e., all * pointers are NULL or point to valid states). Any states which exist in * both are expected to be identical and the state already in dst is used. * The only exception here is render pass state which may be only partially * defined in which case the fully defined one (if any) is used. * * @param[out] dst The destination state. When the function returns, this * will be the union of the original dst and src. * @param[in] src The source state */ void vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst, const struct vk_graphics_pipeline_state *src); extern const struct vk_dynamic_graphics_state vk_default_dynamic_graphics_state; /** Initialize a vk_dynamic_graphics_state with defaults * * @param[out] dyn Dynamic graphics state to initizlie */ void vk_dynamic_graphics_state_init(struct vk_dynamic_graphics_state *dyn); /** Clear a vk_dynamic_graphics_state to defaults * * @param[out] dyn Dynamic graphics state to initizlie */ void vk_dynamic_graphics_state_clear(struct vk_dynamic_graphics_state *dyn); /** Initialize a vk_dynamic_graphics_state for a pipeline * * @param[out] dyn Dynamic graphics state to initizlie * @param[in] supported Bitset of all dynamic state supported by the driver. * @param[in] p The pipeline state from which to initialize the * dynamic state. */ void vk_dynamic_graphics_state_fill(struct vk_dynamic_graphics_state *dyn, const struct vk_graphics_pipeline_state *p); /** Mark all states in the given vk_dynamic_graphics_state dirty * * @param[out] d Dynamic graphics state struct */ static inline void vk_dynamic_graphics_state_dirty_all(struct vk_dynamic_graphics_state *d) { BITSET_SET_RANGE(d->dirty, 0, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX - 1); } /** Mark all states in the given vk_dynamic_graphics_state not dirty * * @param[out] d Dynamic graphics state struct */ static inline void vk_dynamic_graphics_state_clear_dirty(struct vk_dynamic_graphics_state *d) { BITSET_ZERO(d->dirty); } /** Test if any states in the given vk_dynamic_graphics_state are dirty * * @param[in] d Dynamic graphics state struct to test * @returns true if any state is dirty */ static inline bool vk_dynamic_graphics_state_any_dirty(const struct vk_dynamic_graphics_state *d) { return BITSET_TEST_RANGE(d->dirty, 0, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX - 1); } /** Copies all set state from src to dst * * Both src and dst are assumed to be properly initialized dynamic state * structs. Anything not set in src, as indicated by src->set, is ignored and * those bits of dst are left untouched. * * @param[out] dst Copy destination * @param[in] src Copy source */ void vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state *dst, const struct vk_dynamic_graphics_state *src); /** Set all of the state in src on a command buffer * * Anything not set, as indicated by src->set, is ignored and those states in * the command buffer are left untouched. * * @param[inout] cmd Command buffer to update * @param[in] src State to set */ void vk_cmd_set_dynamic_graphics_state(struct vk_command_buffer *cmd, const struct vk_dynamic_graphics_state *src); /** Set vertex binding strides on a command buffer * * This is the dynamic state part of vkCmdBindVertexBuffers2(). * * @param[inout] cmd Command buffer to update * @param[in] first_binding First binding to update * @param[in] binding_count Number of bindings to update * @param[in] strides binding_count many stride values to set */ void vk_cmd_set_vertex_binding_strides(struct vk_command_buffer *cmd, uint32_t first_binding, uint32_t binding_count, const VkDeviceSize *strides); #ifdef __cplusplus } #endif #endif /* VK_GRAPHICS_STATE_H */