• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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