In the C23 standard unreachable() is now a predefined function-like macro in <stddef.h> See https://android.googlesource.com/platform/bionic/+/HEAD/docs/c23.md#is-now-a-predefined-function_like-macro-in And this causes build errors when building for C23: ----------------------------------------------------------------------- In file included from ../src/util/log.h:30, from ../src/util/log.c:30: ../src/util/macros.h:123:9: warning: "unreachable" redefined 123 | #define unreachable(str) \ | ^~~~~~~~~~~ In file included from ../src/util/macros.h:31: /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h:456:9: note: this is the location of the previous definition 456 | #define unreachable() (__builtin_unreachable ()) | ^~~~~~~~~~~ ----------------------------------------------------------------------- So don't redefine it with the same name, but use the name UNREACHABLE() to also signify it's a macro. Using a different name also makes sense because the behavior of the macro was extending the one of __builtin_unreachable() anyway, and it also had a different signature, accepting one argument, compared to the standard unreachable() with no arguments. This change improves the chances of building mesa with the C23 standard, which for instance is the default in recent AOSP versions. All the instances of the macro, including the definition, were updated with the following command line: git grep -l '[^_]unreachable(' -- "src/**" | sort | uniq | \ while read file; \ do \ sed -e 's/\([^_]\)unreachable(/\1UNREACHABLE(/g' -i "$file"; \ done && \ sed -e 's/#undef unreachable/#undef UNREACHABLE/g' -i src/intel/isl/isl_aux_info.c Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36437>
1322 lines
42 KiB
C
1322 lines
42 KiB
C
/*
|
|
* 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"
|
|
#include "util/enum_operators.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 abbreviation 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_BINDINGS_VALID,
|
|
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_TS_DOMAIN_ORIGIN,
|
|
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_VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE,
|
|
MESA_VK_DYNAMIC_VP_DEPTH_CLAMP_RANGE,
|
|
MESA_VK_DYNAMIC_DR_RECTANGLES,
|
|
MESA_VK_DYNAMIC_DR_MODE,
|
|
MESA_VK_DYNAMIC_DR_ENABLE,
|
|
MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE,
|
|
MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE,
|
|
MESA_VK_DYNAMIC_RS_DEPTH_CLIP_ENABLE,
|
|
MESA_VK_DYNAMIC_RS_POLYGON_MODE,
|
|
MESA_VK_DYNAMIC_RS_CULL_MODE,
|
|
MESA_VK_DYNAMIC_RS_FRONT_FACE,
|
|
MESA_VK_DYNAMIC_RS_CONSERVATIVE_MODE,
|
|
MESA_VK_DYNAMIC_RS_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE,
|
|
MESA_VK_DYNAMIC_RS_RASTERIZATION_ORDER_AMD,
|
|
MESA_VK_DYNAMIC_RS_PROVOKING_VERTEX,
|
|
MESA_VK_DYNAMIC_RS_RASTERIZATION_STREAM,
|
|
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_MODE,
|
|
MESA_VK_DYNAMIC_RS_LINE_STIPPLE_ENABLE,
|
|
MESA_VK_DYNAMIC_RS_LINE_STIPPLE,
|
|
MESA_VK_DYNAMIC_FSR,
|
|
MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES,
|
|
MESA_VK_DYNAMIC_MS_SAMPLE_MASK,
|
|
MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE,
|
|
MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE,
|
|
MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS_ENABLE,
|
|
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_ENABLE,
|
|
MESA_VK_DYNAMIC_CB_LOGIC_OP,
|
|
MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT,
|
|
MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES,
|
|
MESA_VK_DYNAMIC_CB_BLEND_ENABLES,
|
|
MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS,
|
|
MESA_VK_DYNAMIC_CB_WRITE_MASKS,
|
|
MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS,
|
|
MESA_VK_DYNAMIC_RP_ATTACHMENTS,
|
|
MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE,
|
|
MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP,
|
|
MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP,
|
|
|
|
/* Must be left at the end */
|
|
MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX,
|
|
};
|
|
|
|
#define MESA_VK_ATTACHMENT_UNUSED (0xff)
|
|
|
|
/* This means that input attachments without an index map to this attachment.
|
|
* It is only used for depth and stencil attachments.
|
|
*/
|
|
#define MESA_VK_ATTACHMENT_NO_INDEX (0xfe)
|
|
|
|
/** Populate a bitset with dynamic states
|
|
*
|
|
* This function maps a VkPipelineDynamicStateCreateInfo to a bitset indexed
|
|
* by mesa_vk_dynamic_graphics_state enumerants.
|
|
*
|
|
* :param dynamic: |out| Bitset to populate
|
|
* :param info: |in| 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;
|
|
|
|
/** VkVertexInputBindingDivisorDescriptionKHR::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
|
|
*
|
|
* MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS
|
|
*/
|
|
uint8_t patch_control_points;
|
|
|
|
/** VkPipelineTessellationDomainOriginStateCreateInfo::domainOrigin
|
|
*
|
|
* MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN
|
|
*/
|
|
uint8_t domain_origin;
|
|
};
|
|
|
|
/***/
|
|
struct vk_viewport_state {
|
|
/** VkPipelineViewportDepthClipControlCreateInfoEXT::negativeOneToOne
|
|
*/
|
|
bool depth_clip_negative_one_to_one;
|
|
|
|
/** VkPipelineViewportDepthClampControlCreateInfoEXT::depthClampMode
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_DEPTH_CLAMP_RANGE
|
|
*/
|
|
VkDepthClampModeEXT depth_clamp_mode;
|
|
|
|
/** VkPipelineViewportDepthClampControlCreateInfoEXT::pDepthClampRange
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_DEPTH_CLAMP_RANGE
|
|
*/
|
|
VkDepthClampRangeEXT depth_clamp_range;
|
|
|
|
/** VkPipelineViewportStateCreateInfo::viewportCount
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_VIEWPORT_COUNT
|
|
*/
|
|
uint8_t viewport_count;
|
|
|
|
/** VkPipelineViewportStateCreateInfo::scissorCount
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_SCISSOR_COUNT
|
|
*/
|
|
uint8_t scissor_count;
|
|
|
|
/** VkPipelineViewportStateCreateInfo::pViewports
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_VIEWPORTS
|
|
*/
|
|
VkViewport viewports[MESA_VK_MAX_VIEWPORTS];
|
|
|
|
/** VkPipelineViewportStateCreateInfo::pScissors
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_VP_SCISSORS
|
|
*/
|
|
VkRect2D scissors[MESA_VK_MAX_SCISSORS];
|
|
};
|
|
|
|
/***/
|
|
struct vk_discard_rectangles_state {
|
|
/** VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleMode */
|
|
VkDiscardRectangleModeEXT mode;
|
|
|
|
/** VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleCount */
|
|
uint32_t rectangle_count;
|
|
|
|
/** VkPipelineDiscardRectangleStateCreateInfoEXT::pDiscardRectangles */
|
|
VkRect2D rectangles[MESA_VK_MAX_DISCARD_RECTANGLES];
|
|
};
|
|
|
|
enum ENUM_PACKED vk_mesa_depth_clip_enable {
|
|
/** Depth clipping should be disabled */
|
|
VK_MESA_DEPTH_CLIP_ENABLE_FALSE = 0,
|
|
|
|
/** Depth clipping should be enabled */
|
|
VK_MESA_DEPTH_CLIP_ENABLE_TRUE = 1,
|
|
|
|
/** Depth clipping should be enabled iff depth clamping is disabled */
|
|
VK_MESA_DEPTH_CLIP_ENABLE_NOT_CLAMP,
|
|
};
|
|
|
|
/***/
|
|
struct vk_rasterization_state {
|
|
/** VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable
|
|
*
|
|
* This will be false if rasterizer discard is dynamic
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE
|
|
*/
|
|
bool rasterizer_discard_enable;
|
|
|
|
/** VkPipelineRasterizationStateCreateInfo::depthClampEnable
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE
|
|
*/
|
|
bool depth_clamp_enable;
|
|
|
|
/** VkPipelineRasterizationDepthClipStateCreateInfoEXT::depthClipEnable
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_DEPTH_CLIP_ENABLE
|
|
*/
|
|
enum vk_mesa_depth_clip_enable depth_clip_enable;
|
|
|
|
/** VkPipelineRasterizationStateCreateInfo::polygonMode
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_POLYGON_MODE_ENABLEDEPTH_CLIP_ENABLE
|
|
*/
|
|
VkPolygonMode polygon_mode;
|
|
|
|
/** VkPipelineRasterizationStateCreateInfo::cullMode
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_CULL_MODE
|
|
*/
|
|
VkCullModeFlags cull_mode;
|
|
|
|
/** VkPipelineRasterizationStateCreateInfo::frontFace
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_FRONT_FACE
|
|
*/
|
|
VkFrontFace front_face;
|
|
|
|
/** VkPipelineRasterizationConservativeStateCreateInfoEXT::conservativeRasterizationMode
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_CONSERVATIVE_MODE
|
|
*/
|
|
VkConservativeRasterizationModeEXT conservative_mode;
|
|
|
|
/** VkPipelineRasterizationConservativeStateCreateInfoEXT::extraPrimitiveOverestimationSize
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE
|
|
*/
|
|
float extra_primitive_overestimation_size;
|
|
|
|
/** VkPipelineRasterizationStateRasterizationOrderAMD::rasterizationOrder */
|
|
VkRasterizationOrderAMD rasterization_order_amd;
|
|
|
|
/** VkPipelineRasterizationProvokingVertexStateCreateInfoEXT::provokingVertexMode
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_PROVOKING_VERTEX
|
|
*/
|
|
VkProvokingVertexModeEXT provoking_vertex;
|
|
|
|
/** VkPipelineRasterizationStateStreamCreateInfoEXT::rasterizationStream
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_RASTERIZATION_STREAM
|
|
*/
|
|
uint32_t rasterization_stream;
|
|
|
|
struct {
|
|
/** VkPipelineRasterizationStateCreateInfo::depthBiasEnable
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE
|
|
*/
|
|
bool enable;
|
|
|
|
/** VkPipelineRasterizationStateCreateInfo::depthBiasConstantFactor
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
|
|
*/
|
|
float constant_factor;
|
|
|
|
/** VkPipelineRasterizationStateCreateInfo::depthBiasClamp
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
|
|
*/
|
|
float clamp;
|
|
|
|
/** VkPipelineRasterizationStateCreateInfo::depthBiasSlopeFactor
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
|
|
*/
|
|
float slope_factor;
|
|
|
|
/** VkDepthBiasRepresentationInfoEXT::depthBiasRepresentation
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
|
|
*/
|
|
VkDepthBiasRepresentationEXT representation;
|
|
|
|
/** VkDepthBiasRepresentationInfoEXT::depthBiasExact
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS
|
|
*/
|
|
bool exact;
|
|
} depth_bias;
|
|
|
|
struct {
|
|
/** VkPipelineRasterizationStateCreateInfo::lineWidth
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_LINE_WIDTH
|
|
*/
|
|
float width;
|
|
|
|
/** VkPipelineRasterizationLineStateCreateInfoKHR::lineRasterizationMode
|
|
*
|
|
* Will be set to VK_LINE_RASTERIZATION_MODE_DEFAULT_KHR if
|
|
* VkPipelineRasterizationLineStateCreateInfoKHR is not provided.
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_LINE_MODE
|
|
*/
|
|
VkLineRasterizationModeKHR mode;
|
|
|
|
struct {
|
|
/** VkPipelineRasterizationLineStateCreateInfoKHR::stippledLineEnable
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_LINE_STIPPLE_ENABLE
|
|
*/
|
|
bool enable;
|
|
|
|
/** VkPipelineRasterizationLineStateCreateInfoKHR::lineStippleFactor
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_LINE_STIPPLE
|
|
*/
|
|
uint32_t factor;
|
|
|
|
/** VkPipelineRasterizationLineStateCreateInfoKHR::lineStipplePattern
|
|
*
|
|
* MESA_VK_DYNAMIC_RS_LINE_STIPPLE
|
|
*/
|
|
uint16_t pattern;
|
|
} stipple;
|
|
} line;
|
|
};
|
|
|
|
static inline bool
|
|
vk_rasterization_state_depth_clip_enable(const struct vk_rasterization_state *rs)
|
|
{
|
|
switch (rs->depth_clip_enable) {
|
|
case VK_MESA_DEPTH_CLIP_ENABLE_FALSE: return false;
|
|
case VK_MESA_DEPTH_CLIP_ENABLE_TRUE: return true;
|
|
case VK_MESA_DEPTH_CLIP_ENABLE_NOT_CLAMP: return !rs->depth_clamp_enable;
|
|
}
|
|
UNREACHABLE("Invalid depth clip enable");
|
|
}
|
|
|
|
/***/
|
|
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];
|
|
};
|
|
|
|
static inline bool
|
|
vk_fragment_shading_rate_is_disabled(const struct vk_fragment_shading_rate_state *fsr)
|
|
{
|
|
return fsr->fragment_size.width == 1 &&
|
|
fsr->fragment_size.height == 1 &&
|
|
fsr->combiner_ops[0] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR &&
|
|
fsr->combiner_ops[1] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
|
|
}
|
|
|
|
/***/
|
|
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
|
|
*
|
|
* This will be true if sample locations enable dynamic.
|
|
*/
|
|
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 ds: |inout| The depth stencil state to optimize
|
|
* :param ds_aspects: |in| Which image aspects are present in the
|
|
* render pass.
|
|
* :param consider_write_mask: |in| If true, the write mask will be taken
|
|
* into account when optimizing. If
|
|
* false, it will be ignored.
|
|
*/
|
|
void vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
|
|
VkImageAspectFlags ds_aspects,
|
|
bool consider_write_mask);
|
|
|
|
struct vk_color_blend_attachment_state {
|
|
/** VkPipelineColorBlendAttachmentState::blendEnable
|
|
*
|
|
* This will be true if blend enables are dynamic
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_BLEND_ENABLES
|
|
*/
|
|
bool blend_enable;
|
|
|
|
/** VkPipelineColorBlendAttachmentState::srcColorBlendFactor
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
|
|
*/
|
|
uint8_t src_color_blend_factor;
|
|
|
|
/** VkPipelineColorBlendAttachmentState::dstColorBlendFactor
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
|
|
*/
|
|
uint8_t dst_color_blend_factor;
|
|
|
|
/** VkPipelineColorBlendAttachmentState::srcAlphaBlendFactor
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
|
|
*/
|
|
uint8_t src_alpha_blend_factor;
|
|
|
|
/** VkPipelineColorBlendAttachmentState::dstAlphaBlendFactor
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
|
|
*/
|
|
uint8_t dst_alpha_blend_factor;
|
|
|
|
/** VkPipelineColorBlendAttachmentState::colorWriteMask
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_WRITE_MASKS
|
|
*/
|
|
uint8_t write_mask;
|
|
|
|
/** VkPipelineColorBlendAttachmentState::colorBlendOp
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
|
|
*/
|
|
VkBlendOp color_blend_op;
|
|
|
|
/** VkPipelineColorBlendAttachmentState::alphaBlendOp
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS
|
|
*/
|
|
VkBlendOp alpha_blend_op;
|
|
};
|
|
|
|
/***/
|
|
struct vk_color_blend_state {
|
|
/** VkPipelineColorBlendStateCreateInfo::logicOpEnable
|
|
*
|
|
* MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE,
|
|
*/
|
|
bool logic_op_enable;
|
|
|
|
/** VkPipelineColorBlendStateCreateInfo::logicOp
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_LOGIC_OP,
|
|
*/
|
|
uint8_t logic_op;
|
|
|
|
/** VkPipelineColorBlendStateCreateInfo::attachmentCount
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_ATTACHMENT_COUNT,
|
|
*/
|
|
uint8_t attachment_count;
|
|
|
|
/** VkPipelineColorWriteCreateInfoEXT::pColorWriteEnables
|
|
*
|
|
* Bitmask of color write enables, indexed by color attachment index.
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_COLOR_WRITE_ENABLES,
|
|
*/
|
|
uint8_t color_write_enables;
|
|
|
|
/** VkPipelineColorBlendStateCreateInfo::pAttachments */
|
|
struct vk_color_blend_attachment_state attachments[MESA_VK_MAX_COLOR_ATTACHMENTS];
|
|
|
|
/** VkPipelineColorBlendStateCreateInfo::blendConstants
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_CB_BLEND_CONSTANTS,
|
|
*/
|
|
float blend_constants[4];
|
|
};
|
|
|
|
enum vk_rp_attachment_flags {
|
|
MESA_VK_RP_ATTACHMENT_NONE = 0,
|
|
|
|
MESA_VK_RP_ATTACHMENT_COLOR_0_BIT = (1 << 0),
|
|
MESA_VK_RP_ATTACHMENT_COLOR_1_BIT = (1 << 1),
|
|
MESA_VK_RP_ATTACHMENT_COLOR_2_BIT = (1 << 2),
|
|
MESA_VK_RP_ATTACHMENT_COLOR_3_BIT = (1 << 3),
|
|
MESA_VK_RP_ATTACHMENT_COLOR_4_BIT = (1 << 4),
|
|
MESA_VK_RP_ATTACHMENT_COLOR_5_BIT = (1 << 5),
|
|
MESA_VK_RP_ATTACHMENT_COLOR_6_BIT = (1 << 6),
|
|
MESA_VK_RP_ATTACHMENT_COLOR_7_BIT = (1 << 7),
|
|
MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS = 0xff,
|
|
|
|
MESA_VK_RP_ATTACHMENT_DEPTH_BIT = (1 << 8),
|
|
MESA_VK_RP_ATTACHMENT_STENCIL_BIT = (1 << 9),
|
|
|
|
MESA_VK_RP_ATTACHMENT_INFO_INVALID = 0xffff,
|
|
};
|
|
MESA_DEFINE_CPP_ENUM_BITFIELD_OPERATORS(vk_rp_attachment_flags)
|
|
static_assert(MESA_VK_MAX_COLOR_ATTACHMENTS == 8,
|
|
"This enum must match the global runtime limit");
|
|
|
|
#define MESA_VK_RP_ATTACHMENT_COLOR_BIT(n) \
|
|
((enum vk_rp_attachment_flags)(MESA_VK_RP_ATTACHMENT_COLOR_0_BIT << (n)))
|
|
|
|
#define MESA_VK_COLOR_ATTACHMENT_COUNT_UNKNOWN 0xff
|
|
|
|
/***/
|
|
struct vk_input_attachment_location_state {
|
|
/** VkRenderingInputAttachmentIndexInfoKHR::pColorAttachmentLocations
|
|
*
|
|
* MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP
|
|
*/
|
|
uint8_t color_map[MESA_VK_MAX_COLOR_ATTACHMENTS];
|
|
|
|
/** VkRenderingInputAttachmentIndexInfoKHR::colorAttachmentCount
|
|
*
|
|
* This must match vk_render_pass_state::color_attachment_count or be equal
|
|
* to MESA_VK_COLOR_ATTACHMENT_COUNT_UNKNOWN, in which case it can be
|
|
* assumed that there is an identity mapping and every input attachment
|
|
* with an index is a color attachment. Unlike vk_render_pass_state this
|
|
* state is available when compiling the fragment shader.
|
|
*
|
|
* MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP
|
|
*/
|
|
uint8_t color_attachment_count;
|
|
|
|
/** VkRenderingInputAttachmentIndexInfoKHR::pDepthInputAttachmentIndex
|
|
*
|
|
* MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP
|
|
*/
|
|
uint8_t depth_att;
|
|
|
|
/** VkRenderingInputAttachmentIndexInfoKHR::pStencilInputAttachmentIndex
|
|
*
|
|
* MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP
|
|
*/
|
|
uint8_t stencil_att;
|
|
};
|
|
|
|
/***/
|
|
struct vk_color_attachment_location_state {
|
|
/** VkRenderingAttachmentLocationInfoKHR::pColorAttachmentLocations
|
|
*
|
|
* MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP
|
|
*/
|
|
uint8_t color_map[MESA_VK_MAX_COLOR_ATTACHMENTS];
|
|
};
|
|
|
|
/***/
|
|
struct vk_render_pass_state {
|
|
/** Set of image aspects bound as color/depth/stencil attachments
|
|
*
|
|
* Set to MESA_VK_RP_ATTACHMENT_INFO_INVALID to indicate that attachment
|
|
* info is invalid.
|
|
*/
|
|
enum vk_rp_attachment_flags attachments;
|
|
|
|
/** VkPipelineRenderingCreateInfo::viewMask */
|
|
uint32_t view_mask;
|
|
|
|
/** 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;
|
|
|
|
/** VkAttachmentSampleCountInfoAMD::pColorAttachmentSamples */
|
|
uint8_t color_attachment_samples[MESA_VK_MAX_COLOR_ATTACHMENTS];
|
|
|
|
/** VkAttachmentSampleCountInfoAMD::depthStencilAttachmentSamples */
|
|
uint8_t depth_stencil_attachment_samples;
|
|
};
|
|
|
|
static inline bool
|
|
vk_render_pass_state_has_attachment_info(const struct vk_render_pass_state *rp)
|
|
{
|
|
return rp->attachments != MESA_VK_RP_ATTACHMENT_INFO_INVALID;
|
|
}
|
|
|
|
static inline VkImageAspectFlags
|
|
vk_pipeline_flags_feedback_loops(VkPipelineCreateFlags2KHR flags)
|
|
{
|
|
VkImageAspectFlags feedback_loops = 0;
|
|
if (flags &
|
|
VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
|
|
feedback_loops |= VK_IMAGE_ASPECT_COLOR_BIT;
|
|
if (flags &
|
|
VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
|
|
feedback_loops |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
return feedback_loops;
|
|
}
|
|
|
|
/** 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;
|
|
|
|
/* This is a copy of vi->bindings_valid, used when the vertex input state
|
|
* is precompiled in the pipeline (so that vi is NULL) but the strides are
|
|
* set dynamically.
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_VI_BINDINGS_VALID
|
|
*/
|
|
uint32_t vi_bindings_valid;
|
|
|
|
/** Vertex binding strides
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_VI_BINDING_STRIDES
|
|
*/
|
|
uint16_t vi_binding_strides[MESA_VK_MAX_VERTEX_BINDINGS];
|
|
|
|
/** Input assembly state */
|
|
struct vk_input_assembly_state ia;
|
|
|
|
/** Tessellation state */
|
|
struct vk_tessellation_state ts;
|
|
|
|
/** Viewport state */
|
|
struct vk_viewport_state vp;
|
|
|
|
/** Discard rectangles state */
|
|
struct {
|
|
/** Custom enable
|
|
*
|
|
* MESA_VK_DYNAMIC_DR_ENABLE
|
|
*/
|
|
bool enable;
|
|
|
|
/** Mode
|
|
*
|
|
* MESA_VK_DYNAMIC_DR_MODE
|
|
*/
|
|
VkDiscardRectangleModeEXT mode;
|
|
|
|
/** Rectangles
|
|
*
|
|
* MESA_VK_DYNAMIC_DR_RECTANGLES
|
|
*/
|
|
VkRect2D rectangles[MESA_VK_MAX_DISCARD_RECTANGLES];
|
|
|
|
/** Number of rectangles
|
|
*
|
|
* MESA_VK_DYNAMIC_GRAPHICS_STATE_DR_RECTANGLES
|
|
*/
|
|
uint32_t rectangle_count;
|
|
} dr;
|
|
|
|
/** Rasterization state */
|
|
struct vk_rasterization_state rs;
|
|
|
|
/* Fragment shading rate state */
|
|
struct vk_fragment_shading_rate_state fsr;
|
|
|
|
/** Multisample state */
|
|
struct {
|
|
/** Rasterization samples
|
|
*
|
|
* MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES
|
|
*/
|
|
VkSampleCountFlagBits rasterization_samples;
|
|
|
|
/** Sample mask
|
|
*
|
|
* MESA_VK_DYNAMIC_MS_SAMPLE_MASK
|
|
*/
|
|
uint16_t sample_mask;
|
|
|
|
/** Alpha to coverage enable
|
|
*
|
|
* MESA_VK_DYNAMIC_MS_ALPHA_TO_CONVERAGE_ENABLE
|
|
*/
|
|
bool alpha_to_coverage_enable;
|
|
|
|
/** Alpha to one enable
|
|
*
|
|
* MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE
|
|
*/
|
|
bool alpha_to_one_enable;
|
|
|
|
/** Custom sample locations enable
|
|
*
|
|
* MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS_ENABLE
|
|
*/
|
|
bool sample_locations_enable;
|
|
|
|
/** Sample locations
|
|
*
|
|
* Must be provided by the driver if VK_EXT_sample_locations is
|
|
* supported.
|
|
*
|
|
* MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS
|
|
*/
|
|
struct vk_sample_locations_state *sample_locations;
|
|
} ms;
|
|
|
|
/** Depth stencil state */
|
|
struct vk_depth_stencil_state ds;
|
|
|
|
/** Color blend state */
|
|
struct vk_color_blend_state cb;
|
|
|
|
struct {
|
|
enum vk_rp_attachment_flags attachments;
|
|
} rp;
|
|
|
|
/** MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE */
|
|
VkImageAspectFlags feedback_loops;
|
|
|
|
/** MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP */
|
|
struct vk_input_attachment_location_state ial;
|
|
|
|
/** MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP */
|
|
struct vk_color_attachment_location_state cal;
|
|
|
|
/** 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_input_attachment_location_state ial;
|
|
struct vk_color_attachment_location_state cal;
|
|
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);
|
|
|
|
VkShaderStageFlags shader_stages;
|
|
|
|
/** Flags from VkGraphicsPipelineCreateInfo::flags that are considered part
|
|
* of a stage and need to be merged when linking libraries.
|
|
*
|
|
* For drivers which use vk_render_pass, this will also include flags
|
|
* generated based on subpass self-dependencies and fragment density map.
|
|
*/
|
|
VkPipelineCreateFlags2KHR pipeline_flags;
|
|
|
|
/* True if there are feedback loops that do not involve input attachments
|
|
* managed by the driver. This is set to true by the runtime if there
|
|
* are loops indicated by a pipeline flag (which may involve any image
|
|
* rather than only input attachments under the control of the driver) or
|
|
* there was no driver-provided render pass info struct (because input
|
|
* attachments for emulated renderpasses cannot be managed by the driver).
|
|
*/
|
|
bool feedback_loop_not_input_only;
|
|
|
|
/** 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;
|
|
|
|
/** Multisample 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;
|
|
|
|
/** Input attachment mapping state */
|
|
const struct vk_input_attachment_location_state *ial;
|
|
|
|
/** Color attachment mapping state */
|
|
const struct vk_color_attachment_location_state *cal;
|
|
|
|
/** Render pass state */
|
|
const struct vk_render_pass_state *rp;
|
|
};
|
|
|
|
/** 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 device: |in| The Vulkan device
|
|
* :param state: |out| The graphics pipeline state to populate
|
|
* :param info: |in| The pCreateInfo from vkCreateGraphicsPipelines
|
|
* :param driver_rp: |in| Renderpass state 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 driver_rp_flags: |in| Pipeline create flags implied by the
|
|
* renderpass or subpass if the driver implements
|
|
* render passes itself. This is only used if
|
|
* driver_rp is non-NULL.
|
|
* :param all: |in| 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 alloc: |in| Allocation callbacks for dynamically allocating
|
|
* new state memory.
|
|
* :param scope: |in| Allocation scope for dynamically allocating new
|
|
* state memory.
|
|
* :param alloc_ptr_out: |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_render_pass_state *driver_rp,
|
|
VkPipelineCreateFlags2KHR driver_rp_flags,
|
|
struct vk_graphics_pipeline_all_state *all,
|
|
const VkAllocationCallbacks *alloc,
|
|
VkSystemAllocationScope scope,
|
|
void **alloc_ptr_out);
|
|
|
|
/** Populate a vk_graphics_pipeline_state from another one.
|
|
*
|
|
* This allocates space for graphics pipeline state and copies it from another
|
|
* pipeline state. It ignores state in `old_state` which is not set and does
|
|
* not allocate memory if the entire group is unused. The intended use-case is
|
|
* for drivers that may be able to precompile some state ahead of time, to
|
|
* avoid allocating memory for it in pipeline libraries. The workflow looks
|
|
* something like this:
|
|
*
|
|
* struct vk_graphics_pipeline_all_state all;
|
|
* struct vk_graphics_pipeline_state state;
|
|
* vk_graphics_pipeline_state_fill(dev, &state, ..., &all, NULL, 0, NULL);
|
|
*
|
|
* ...
|
|
*
|
|
* BITSET_DECLARE(set_state, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
|
|
* vk_graphics_pipeline_get_state(&state, &set_state);
|
|
*
|
|
* ...
|
|
*
|
|
* if (BITSET_TEST(set_state, MESA_VK_DYNAMIC_FOO)) {
|
|
* emit_foo(&state.foo, ...);
|
|
* BITSET_SET(state.dynamic, MESA_VK_DYNAMIC_FOO);
|
|
* }
|
|
*
|
|
* ...
|
|
*
|
|
* if (pipeline->is_library) {
|
|
* library = pipeline_to_library(pipeline);
|
|
* vk_graphics_pipeline_state_copy(dev, &library->state, &state, ...);
|
|
* }
|
|
*
|
|
* In this case we will avoid allocating memory for `library->state.foo`.
|
|
*
|
|
* :param device: |in| The Vulkan device
|
|
* :param state: |out| The graphics pipeline state to populate
|
|
* :param old_state: |in| The graphics pipeline state to copy from
|
|
* :param alloc: |in| Allocation callbacks for dynamically allocating
|
|
* new state memory.
|
|
* :param scope: |in| Allocation scope for dynamically allocating new
|
|
* state memory.
|
|
* :param alloc_ptr_out: |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_copy(const struct vk_device *device,
|
|
struct vk_graphics_pipeline_state *state,
|
|
const struct vk_graphics_pipeline_state *old_state,
|
|
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 dst: |out| The destination state. When the function returns, this
|
|
* will be the union of the original dst and src.
|
|
* :param src: |in| The source state
|
|
*/
|
|
void
|
|
vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst,
|
|
const struct vk_graphics_pipeline_state *src);
|
|
|
|
/** Get the states which will be set for a given vk_graphics_pipeline_state
|
|
*
|
|
* Return which states should be set when the pipeline is bound.
|
|
*/
|
|
void
|
|
vk_graphics_pipeline_get_state(const struct vk_graphics_pipeline_state *state,
|
|
BITSET_WORD *set_state_out);
|
|
|
|
/** Initialize a vk_dynamic_graphics_state with defaults
|
|
*
|
|
* :param dyn: |out| Dynamic graphics state to initialize
|
|
*/
|
|
void
|
|
vk_dynamic_graphics_state_init(struct vk_dynamic_graphics_state *dyn);
|
|
|
|
/** Clear a vk_dynamic_graphics_state to defaults
|
|
*
|
|
* :param dyn: |out| Dynamic graphics state to initialize
|
|
*/
|
|
void
|
|
vk_dynamic_graphics_state_clear(struct vk_dynamic_graphics_state *dyn);
|
|
|
|
/** Initialize a vk_dynamic_graphics_state for a pipeline
|
|
*
|
|
* :param dyn: |out| Dynamic graphics state to initialize
|
|
* :param supported: |in| Bitset of all dynamic state supported by the driver.
|
|
* :param p: |in| 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 d: |out| 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 d: |out| 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 d: |in| 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_IS_EMPTY(d->dirty);
|
|
}
|
|
|
|
/** 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 dst: |out| Copy destination
|
|
* :param src: |in| 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 cmd: |inout| Command buffer to update
|
|
* :param src: |in| 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 cmd: |inout| Command buffer to update
|
|
* :param first_binding: |in| First binding to update
|
|
* :param binding_count: |in| Number of bindings to update
|
|
* :param strides: |in| 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);
|
|
|
|
/* Set color attachment count for blending on a command buffer.
|
|
*
|
|
* This is an implicit part of starting a subpass or a secondary command
|
|
* buffer in a subpass.
|
|
*/
|
|
void
|
|
vk_cmd_set_cb_attachment_count(struct vk_command_buffer *cmd,
|
|
uint32_t attachment_count);
|
|
|
|
/* Set render pass attachments on a command buffer.
|
|
*
|
|
* This is required for VK_EXT_shader_object in order to disable attachments
|
|
* based on bound shaders.
|
|
*/
|
|
void
|
|
vk_cmd_set_rp_attachments(struct vk_command_buffer *cmd,
|
|
enum vk_rp_attachment_flags attachments);
|
|
|
|
/* This is equivalent to CmdSetRenderingAttachmentLocationsKHR() but easier to
|
|
* invoke from inside drivers.
|
|
*/
|
|
void
|
|
vk_cmd_set_rendering_attachment_locations(struct vk_command_buffer *cmd,
|
|
const VkRenderingAttachmentLocationInfoKHR *info);
|
|
|
|
const char *
|
|
vk_dynamic_graphic_state_to_str(enum mesa_vk_dynamic_graphics_state state);
|
|
|
|
/** Check whether the color attachment location map is the identity
|
|
*
|
|
* :param cal: |in| Color attachment location state
|
|
*/
|
|
static inline bool
|
|
vk_color_attachment_location_state_is_identity(
|
|
const struct vk_color_attachment_location_state *cal)
|
|
{
|
|
for (unsigned i = 0; i < ARRAY_SIZE(cal->color_map); i++) {
|
|
if (cal->color_map[i] != i)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* VK_GRAPHICS_STATE_H */
|