• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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 sw_PixelProcessor_hpp
16 #define sw_PixelProcessor_hpp
17 
18 #include "Context.hpp"
19 #include "Memset.hpp"
20 #include "RoutineCache.hpp"
21 #include "Vulkan/VkFormat.hpp"
22 
23 #include <memory>
24 
25 namespace sw {
26 
27 struct DrawData;
28 struct Primitive;
29 class SpirvShader;
30 
31 using RasterizerFunction = FunctionT<void(const vk::Device *device, const Primitive *primitive, int count, int cluster, int clusterCount, DrawData *draw)>;
32 
33 class PixelProcessor
34 {
35 public:
36 	struct States : Memset<States>
37 	{
38 		// Same as VkStencilOpState, but with no reference, as it's not part of the state
39 		// (it doesn't require a different program to be generated)
40 		struct StencilOpState
41 		{
42 			VkStencilOp failOp;
43 			VkStencilOp passOp;
44 			VkStencilOp depthFailOp;
45 			VkCompareOp compareOp;
46 			uint32_t compareMask;
47 			uint32_t writeMask;
48 
operator =sw::PixelProcessor::States::StencilOpState49 			void operator=(const VkStencilOpState &rhs)
50 			{
51 				failOp = rhs.failOp;
52 				passOp = rhs.passOp;
53 				depthFailOp = rhs.depthFailOp;
54 				compareOp = rhs.compareOp;
55 				compareMask = rhs.compareMask;
56 				writeMask = rhs.writeMask;
57 			}
58 		};
59 
Statessw::PixelProcessor::States60 		States()
61 		    : Memset(this, 0)
62 		{}
63 
64 		uint32_t computeHash();
65 
66 		uint64_t shaderID;
67 		uint32_t pipelineLayoutIdentifier;
68 
69 		unsigned int numClipDistances;
70 		unsigned int numCullDistances;
71 
72 		VkCompareOp depthCompareMode;
73 		bool depthWriteEnable;
74 
75 		bool stencilActive;
76 		StencilOpState frontStencil;
77 		StencilOpState backStencil;
78 
79 		bool depthTestActive;
80 		bool depthBoundsTestActive;
81 		bool occlusionEnabled;
82 		bool perspective;
83 
84 		vk::BlendState blendState[MAX_COLOR_BUFFERS];
85 
86 		unsigned int colorWriteMask;
87 		vk::Format colorFormat[MAX_COLOR_BUFFERS];
88 		unsigned int multiSampleCount;
89 		unsigned int multiSampleMask;
90 		bool enableMultiSampling;
91 		bool alphaToCoverage;
92 		bool centroid;
93 		bool sampleShadingEnabled;
94 		float minSampleShading;
95 		float minDepthBounds;
96 		float maxDepthBounds;
97 		VkFrontFace frontFace;
98 		vk::Format depthFormat;
99 		bool depthBias;
100 		bool depthClamp;
101 
102 		float minDepthClamp;
103 		float maxDepthClamp;
104 	};
105 
106 	struct State : States
107 	{
108 		bool operator==(const State &state) const;
109 
colorWriteActivesw::PixelProcessor::State110 		int colorWriteActive(int index) const
111 		{
112 			return (colorWriteMask >> (index * 4)) & 0xF;
113 		}
114 
115 		uint32_t hash;
116 	};
117 
118 	struct Stencil
119 	{
120 		int64_t testMaskQ;
121 		int64_t referenceMaskedQ;
122 		int64_t referenceMaskedSignedQ;
123 		int64_t writeMaskQ;
124 		int64_t invWriteMaskQ;
125 		int64_t referenceQ;
126 
setsw::PixelProcessor::Stencil127 		void set(int reference, int testMask, int writeMask)
128 		{
129 			referenceQ = replicate(reference);
130 			testMaskQ = replicate(testMask);
131 			writeMaskQ = replicate(writeMask);
132 			invWriteMaskQ = ~writeMaskQ;
133 			referenceMaskedQ = referenceQ & testMaskQ;
134 			referenceMaskedSignedQ = replicate(((reference & testMask) + 0x80) & 0xFF);
135 		}
136 
replicatesw::PixelProcessor::Stencil137 		static int64_t replicate(int b)
138 		{
139 			int64_t w = b & 0xFF;
140 
141 			return (w << 0) | (w << 8) | (w << 16) | (w << 24) | (w << 32) | (w << 40) | (w << 48) | (w << 56);
142 		}
143 	};
144 
145 	struct Factor
146 	{
147 		float4 blendConstantF;     // Unclamped for floating-point attachment formats.
148 		float4 invBlendConstantF;  // Unclamped for floating-point attachment formats.
149 		float4 blendConstantU;     // Clamped to [0,1] for unsigned fixed-point attachment formats.
150 		float4 invBlendConstantU;  // Clamped to [0,1] for unsigned fixed-point attachment formats.
151 		float4 blendConstantS;     // Clamped to [-1,1] for signed fixed-point attachment formats.
152 		float4 invBlendConstantS;  // Clamped to [-1,1] for signed fixed-point attachment formats.
153 	};
154 
155 public:
156 	using RoutineType = RasterizerFunction::RoutineType;
157 
158 	PixelProcessor();
159 
160 	void setBlendConstant(const float4 &blendConstant);
161 
162 	const State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *fragmentShader, const sw::SpirvShader *vertexShader, const vk::Attachments &attachments, bool occlusionEnabled) const;
163 	RoutineType routine(const State &state, const vk::PipelineLayout *pipelineLayout,
164 	                    const SpirvShader *pixelShader, const vk::DescriptorSet::Bindings &descriptorSets);
165 	void setRoutineCacheSize(int routineCacheSize);
166 
167 	// Other semi-constants
168 	Factor factor;
169 
170 private:
171 	using RoutineCacheType = RoutineCache<State, RasterizerFunction::CFunctionType>;
172 	std::unique_ptr<RoutineCacheType> routineCache;
173 };
174 
175 }  // namespace sw
176 
177 namespace std {
178 
179 template<>
180 struct hash<sw::PixelProcessor::State>
181 {
operator ()std::hash182 	uint64_t operator()(const sw::PixelProcessor::State &state) const
183 	{
184 		return state.hash;
185 	}
186 };
187 
188 }  // namespace std
189 
190 #endif  // sw_PixelProcessor_hpp
191