1 // Copyright 2020 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef vk_Context_hpp 16 #define vk_Context_hpp 17 18 #include "Config.hpp" 19 #include "Memset.hpp" 20 #include "Stream.hpp" 21 #include "System/Types.hpp" 22 #include "Vulkan/VkDescriptorSet.hpp" 23 #include "Vulkan/VkFormat.hpp" 24 25 #include <vector> 26 27 namespace vk { 28 29 class Buffer; 30 class Device; 31 class ImageView; 32 class PipelineLayout; 33 34 struct VertexInputBinding 35 { 36 Buffer *buffer = nullptr; 37 VkDeviceSize offset = 0; 38 VkDeviceSize size = 0; 39 VkDeviceSize stride = 0; 40 }; 41 42 struct IndexBuffer 43 { getIndexTypevk::IndexBuffer44 inline VkIndexType getIndexType() const { return indexType; } 45 void setIndexBufferBinding(const VertexInputBinding &indexBufferBinding, VkIndexType type); 46 void getIndexBuffers(VkPrimitiveTopology topology, uint32_t count, uint32_t first, bool indexed, bool hasPrimitiveRestartEnable, std::vector<std::pair<uint32_t, void *>> *indexBuffers) const; 47 48 private: 49 int bytesPerIndex() const; 50 51 VertexInputBinding binding; 52 VkIndexType indexType; 53 }; 54 55 struct Attachments 56 { 57 ImageView *colorBuffer[sw::MAX_COLOR_BUFFERS] = {}; 58 ImageView *depthBuffer = nullptr; 59 ImageView *stencilBuffer = nullptr; 60 61 VkFormat colorFormat(int index) const; 62 VkFormat depthFormat() const; 63 }; 64 65 struct Inputs 66 { 67 Inputs(const VkPipelineVertexInputStateCreateInfo *vertexInputState); 68 69 void updateDescriptorSets(const DescriptorSet::Array &dso, 70 const DescriptorSet::Bindings &ds, 71 const DescriptorSet::DynamicOffsets &ddo); getDescriptorSetObjectsvk::Inputs72 inline const DescriptorSet::Array &getDescriptorSetObjects() const { return descriptorSetObjects; } getDescriptorSetsvk::Inputs73 inline const DescriptorSet::Bindings &getDescriptorSets() const { return descriptorSets; } getDescriptorDynamicOffsetsvk::Inputs74 inline const DescriptorSet::DynamicOffsets &getDescriptorDynamicOffsets() const { return descriptorDynamicOffsets; } getStreamvk::Inputs75 inline const sw::Stream &getStream(uint32_t i) const { return stream[i]; } 76 77 void bindVertexInputs(int firstInstance); 78 void setVertexInputBinding(const VertexInputBinding vertexInputBindings[]); 79 void advanceInstanceAttributes(); 80 VkDeviceSize getVertexStride(uint32_t i, bool dynamicVertexStride) const; 81 82 private: 83 VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {}; 84 DescriptorSet::Array descriptorSetObjects = {}; 85 DescriptorSet::Bindings descriptorSets = {}; 86 DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {}; 87 sw::Stream stream[sw::MAX_INTERFACE_COMPONENTS / 4]; 88 }; 89 90 struct BlendState : sw::Memset<BlendState> 91 { BlendStatevk::BlendState92 BlendState() 93 : Memset(this, 0) 94 {} 95 BlendStatevk::BlendState96 BlendState(bool alphaBlendEnable, 97 VkBlendFactor sourceBlendFactor, 98 VkBlendFactor destBlendFactor, 99 VkBlendOp blendOperation, 100 VkBlendFactor sourceBlendFactorAlpha, 101 VkBlendFactor destBlendFactorAlpha, 102 VkBlendOp blendOperationAlpha) 103 : Memset(this, 0) 104 , alphaBlendEnable(alphaBlendEnable) 105 , sourceBlendFactor(sourceBlendFactor) 106 , destBlendFactor(destBlendFactor) 107 , blendOperation(blendOperation) 108 , sourceBlendFactorAlpha(sourceBlendFactorAlpha) 109 , destBlendFactorAlpha(destBlendFactorAlpha) 110 , blendOperationAlpha(blendOperationAlpha) 111 {} 112 113 bool alphaBlendEnable; 114 VkBlendFactor sourceBlendFactor; 115 VkBlendFactor destBlendFactor; 116 VkBlendOp blendOperation; 117 VkBlendFactor sourceBlendFactorAlpha; 118 VkBlendFactor destBlendFactorAlpha; 119 VkBlendOp blendOperationAlpha; 120 }; 121 122 struct DynamicState 123 { 124 VkViewport viewport; 125 VkRect2D scissor; 126 sw::float4 blendConstants; 127 float depthBiasConstantFactor = 0.0f; 128 float depthBiasClamp = 0.0f; 129 float depthBiasSlopeFactor = 0.0f; 130 float minDepthBounds = 0.0f; 131 float maxDepthBounds = 0.0f; 132 133 VkCullModeFlags cullMode = VK_CULL_MODE_NONE; 134 VkBool32 depthBoundsTestEnable = VK_FALSE; 135 VkCompareOp depthCompareOp = VK_COMPARE_OP_NEVER; 136 VkBool32 depthTestEnable = VK_FALSE; 137 VkBool32 depthWriteEnable = VK_FALSE; 138 VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 139 VkPrimitiveTopology primitiveTopology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; 140 uint32_t scissorCount = 0; 141 VkRect2D scissors[vk::MAX_VIEWPORTS] = {}; 142 VkStencilFaceFlags faceMask = (VkStencilFaceFlags)0; 143 VkStencilOpState frontStencil = {}; 144 VkStencilOpState backStencil = {}; 145 VkBool32 stencilTestEnable = VK_FALSE; 146 uint32_t viewportCount = 0; 147 VkRect2D viewports[vk::MAX_VIEWPORTS] = {}; 148 VkBool32 rasterizerDiscardEnable = VK_FALSE; 149 VkBool32 depthBiasEnable = VK_FALSE; 150 VkBool32 primitiveRestartEnable = VK_FALSE; 151 }; 152 153 struct GraphicsState 154 { 155 GraphicsState(const Device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo, const PipelineLayout *layout, bool robustBufferAccess); 156 157 const GraphicsState combineStates(const DynamicState &dynamicState) const; 158 getPipelineLayoutvk::GraphicsState159 inline const PipelineLayout *getPipelineLayout() const { return pipelineLayout; } getRobustBufferAccessvk::GraphicsState160 inline bool getRobustBufferAccess() const { return robustBufferAccess; } getTopologyvk::GraphicsState161 inline VkPrimitiveTopology getTopology() const { return topology; } 162 getProvokingVertexModevk::GraphicsState163 inline VkProvokingVertexModeEXT getProvokingVertexMode() const { return provokingVertexMode; } 164 getFrontStencilvk::GraphicsState165 inline VkStencilOpState getFrontStencil() const { return frontStencil; } getBackStencilvk::GraphicsState166 inline VkStencilOpState getBackStencil() const { return backStencil; } 167 168 // Pixel processor states getCullModevk::GraphicsState169 inline VkCullModeFlags getCullMode() const { return cullMode; } getFrontFacevk::GraphicsState170 inline VkFrontFace getFrontFace() const { return frontFace; } getPolygonModevk::GraphicsState171 inline VkPolygonMode getPolygonMode() const { return polygonMode; } getLineRasterizationModevk::GraphicsState172 inline VkLineRasterizationModeEXT getLineRasterizationMode() const { return lineRasterizationMode; } 173 getConstantDepthBiasvk::GraphicsState174 inline float getConstantDepthBias() const { return depthBiasEnable ? constantDepthBias : 0; } getSlopeDepthBiasvk::GraphicsState175 inline float getSlopeDepthBias() const { return depthBiasEnable ? slopeDepthBias : 0; } getDepthBiasClampvk::GraphicsState176 inline float getDepthBiasClamp() const { return depthBiasEnable ? depthBiasClamp : 0; } getMinDepthBoundsvk::GraphicsState177 inline float getMinDepthBounds() const { return minDepthBounds; } getMaxDepthBoundsvk::GraphicsState178 inline float getMaxDepthBounds() const { return maxDepthBounds; } hasDepthRangeUnrestrictedvk::GraphicsState179 inline bool hasDepthRangeUnrestricted() const { return depthRangeUnrestricted; } getDepthClampEnablevk::GraphicsState180 inline bool getDepthClampEnable() const { return depthClampEnable; } getDepthClipEnablevk::GraphicsState181 inline bool getDepthClipEnable() const { return depthClipEnable; } 182 183 // Pixel processor states hasRasterizerDiscardvk::GraphicsState184 inline bool hasRasterizerDiscard() const { return rasterizerDiscard; } getDepthCompareModevk::GraphicsState185 inline VkCompareOp getDepthCompareMode() const { return depthCompareMode; } 186 getLineWidthvk::GraphicsState187 inline float getLineWidth() const { return lineWidth; } 188 getMultiSampleMaskvk::GraphicsState189 inline unsigned int getMultiSampleMask() const { return multiSampleMask; } getSampleCountvk::GraphicsState190 inline int getSampleCount() const { return sampleCount; } hasSampleShadingEnabledvk::GraphicsState191 inline bool hasSampleShadingEnabled() const { return sampleShadingEnable; } getMinSampleShadingvk::GraphicsState192 inline float getMinSampleShading() const { return minSampleShading; } hasAlphaToCoveragevk::GraphicsState193 inline bool hasAlphaToCoverage() const { return alphaToCoverage; } 194 hasPrimitiveRestartEnablevk::GraphicsState195 inline bool hasPrimitiveRestartEnable() const { return primitiveRestartEnable; } getScissorvk::GraphicsState196 inline const VkRect2D &getScissor() const { return scissor; } getViewportvk::GraphicsState197 inline const VkViewport &getViewport() const { return viewport; } getBlendConstantsvk::GraphicsState198 inline const sw::float4 &getBlendConstants() const { return blendConstants; } 199 200 bool isDrawPoint(bool polygonModeAware) const; 201 bool isDrawLine(bool polygonModeAware) const; 202 bool isDrawTriangle(bool polygonModeAware) const; 203 204 BlendState getBlendState(int index, const Attachments &attachments, bool fragmentContainsKill) const; 205 206 int colorWriteActive(int index, const Attachments &attachments) const; 207 bool depthWriteActive(const Attachments &attachments) const; 208 bool depthTestActive(const Attachments &attachments) const; 209 bool stencilActive(const Attachments &attachments) const; 210 bool depthBoundsTestActive(const Attachments &attachments) const; 211 hasDynamicVertexStridevk::GraphicsState212 inline bool hasDynamicVertexStride() const { return dynamicStateFlags.dynamicVertexInputBindingStride; } hasDynamicTopologyvk::GraphicsState213 inline bool hasDynamicTopology() const { return dynamicStateFlags.dynamicPrimitiveTopology; } 214 215 private: 216 struct DynamicStateFlags 217 { 218 bool dynamicViewport : 1; 219 bool dynamicScissor : 1; 220 bool dynamicLineWidth : 1; 221 bool dynamicDepthBias : 1; 222 bool dynamicBlendConstants : 1; 223 bool dynamicDepthBounds : 1; 224 bool dynamicStencilCompareMask : 1; 225 bool dynamicStencilWriteMask : 1; 226 bool dynamicStencilReference : 1; 227 bool dynamicCullMode : 1; 228 bool dynamicFrontFace : 1; 229 bool dynamicPrimitiveTopology : 1; 230 bool dynamicViewportWithCount : 1; 231 bool dynamicScissorWithCount : 1; 232 bool dynamicVertexInputBindingStride : 1; 233 bool dynamicDepthTestEnable : 1; 234 bool dynamicDepthWriteEnable : 1; 235 bool dynamicDepthCompareOp : 1; 236 bool dynamicDepthBoundsTestEnable : 1; 237 bool dynamicStencilTestEnable : 1; 238 bool dynamicStencilOp : 1; 239 bool dynamicRasterizerDiscardEnable : 1; 240 bool dynamicDepthBiasEnable : 1; 241 bool dynamicPrimitiveRestartEnable : 1; 242 }; 243 244 static DynamicStateFlags ParseDynamicStateFlags(const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo); 245 void setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo *depthStencilState); 246 void setColorBlendState(const VkPipelineColorBlendStateCreateInfo *colorBlendState); 247 248 VkBlendFactor blendFactor(VkBlendOp blendOperation, VkBlendFactor blendFactor) const; 249 VkBlendOp blendOperation(VkBlendOp blendOperation, VkBlendFactor sourceBlendFactor, VkBlendFactor destBlendFactor, vk::Format format) const; 250 251 bool alphaBlendActive(int index, const Attachments &attachments, bool fragmentContainsKill) const; 252 bool colorWriteActive(const Attachments &attachments) const; 253 254 const PipelineLayout *pipelineLayout = nullptr; 255 const bool robustBufferAccess = false; 256 const DynamicStateFlags dynamicStateFlags = {}; 257 VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; 258 259 VkProvokingVertexModeEXT provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT; 260 261 bool stencilEnable = false; 262 VkStencilOpState frontStencil = {}; 263 VkStencilOpState backStencil = {}; 264 265 // Pixel processor states 266 VkCullModeFlags cullMode = 0; 267 VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 268 VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL; 269 VkLineRasterizationModeEXT lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT; 270 271 bool depthBiasEnable = false; 272 float constantDepthBias = 0.0f; 273 float slopeDepthBias = 0.0f; 274 float depthBiasClamp = 0.0f; 275 float minDepthBounds = 0.0f; 276 float maxDepthBounds = 0.0f; 277 bool depthRangeUnrestricted = false; 278 279 // Pixel processor states 280 bool rasterizerDiscard = false; 281 bool depthBoundsTestEnable = false; 282 bool depthTestEnable = false; 283 VkCompareOp depthCompareMode = VK_COMPARE_OP_NEVER; 284 bool depthWriteEnable = false; 285 bool depthClampEnable = false; 286 bool depthClipEnable = false; 287 288 float lineWidth = 0.0f; 289 290 int colorWriteMask[sw::MAX_COLOR_BUFFERS] = {}; // RGBA 291 unsigned int multiSampleMask = 0; 292 int sampleCount = 0; 293 bool alphaToCoverage = false; 294 295 bool sampleShadingEnable = false; 296 float minSampleShading = 0.0f; 297 298 bool primitiveRestartEnable = false; 299 VkRect2D scissor = {}; 300 VkViewport viewport = {}; 301 sw::float4 blendConstants = {}; 302 303 BlendState blendState[sw::MAX_COLOR_BUFFERS] = {}; 304 }; 305 306 } // namespace vk 307 308 #endif // vk_Context_hpp 309