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_VertexProcessor_hpp
16 #define sw_VertexProcessor_hpp
17 
18 #include "Matrix.hpp"
19 #include "Context.hpp"
20 #include "RoutineCache.hpp"
21 #include "Pipeline/VertexShader.hpp"
22 #include "Pipeline/SpirvShader.hpp"
23 
24 namespace sw
25 {
26 	struct DrawData;
27 
28 	struct VertexCache   // FIXME: Variable size
29 	{
30 		void clear();
31 
32 		Vertex vertex[16][4];
33 		unsigned int tag[16];
34 
35 		int drawCall;
36 	};
37 
38 	struct VertexTask
39 	{
40 		unsigned int vertexCount;
41 		unsigned int primitiveStart;
42 		VertexCache vertexCache;
43 	};
44 
45 	class VertexProcessor
46 	{
47 	public:
48 		struct States
49 		{
50 			unsigned int computeHash();
51 
52 			uint64_t shaderID;
53 
54 			bool fixedFunction             : 1;   // TODO: Eliminate by querying shader.
55 			bool textureSampling           : 1;   // TODO: Eliminate by querying shader.
56 			unsigned int positionRegister  : BITS(MAX_VERTEX_OUTPUTS);   // TODO: Eliminate by querying shader.
57 			unsigned int pointSizeRegister : BITS(MAX_VERTEX_OUTPUTS);   // TODO: Eliminate by querying shader.
58 
59 			bool transformFeedbackQueryEnabled                : 1;
60 			uint64_t transformFeedbackEnabled                 : 64;
61 			unsigned char verticesPerPrimitive                : 2; // 1 (points), 2 (lines) or 3 (triangles)
62 
63 			bool multiSampling  : 1;
64 
65 			Sampler::State sampler[VERTEX_TEXTURE_IMAGE_UNITS];
66 
67 			struct Input
68 			{
operator boolsw::VertexProcessor::States::Input69 				operator bool() const   // Returns true if stream contains data
70 				{
71 					return count != 0;
72 				}
73 
74 				StreamType type    : BITS(STREAMTYPE_LAST);
75 				unsigned int count : 3;
76 				bool normalized    : 1;
77 				unsigned int attribType : BITS(SpirvShader::ATTRIBTYPE_LAST);
78 			};
79 
80 			struct Output
81 			{
82 				union
83 				{
84 					unsigned char write : 4;
85 
86 					struct
87 					{
88 						unsigned char xWrite : 1;
89 						unsigned char yWrite : 1;
90 						unsigned char zWrite : 1;
91 						unsigned char wWrite : 1;
92 					};
93 				};
94 
95 				union
96 				{
97 					unsigned char clamp : 4;
98 
99 					struct
100 					{
101 						unsigned char xClamp : 1;
102 						unsigned char yClamp : 1;
103 						unsigned char zClamp : 1;
104 						unsigned char wClamp : 1;
105 					};
106 				};
107 			};
108 
109 			Input input[MAX_VERTEX_INPUTS];
110 			Output output[MAX_VERTEX_OUTPUTS];
111 		};
112 
113 		struct State : States
114 		{
115 			State();
116 
117 			bool operator==(const State &state) const;
118 
119 			unsigned int hash;
120 		};
121 
122 		typedef void (*RoutinePointer)(Vertex *output, unsigned int *batch, VertexTask *vertexTask, DrawData *draw);
123 
124 		VertexProcessor(Context *context);
125 
126 		virtual ~VertexProcessor();
127 
128 		void setInputStream(int index, const Stream &stream);
129 		void resetInputStreams();
130 
131 		void setFloatConstant(unsigned int index, const float value[4]);
132 		void setIntegerConstant(unsigned int index, const int integer[4]);
133 		void setBooleanConstant(unsigned int index, int boolean);
134 
135 		void setUniformBuffer(int index, sw::Resource* uniformBuffer, int offset);
136 		void lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);
137 
138 		void setTransformFeedbackBuffer(int index, sw::Resource* transformFeedbackBuffer, int offset, unsigned int reg, unsigned int row, unsigned int col, unsigned int stride);
139 		void lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[]);
140 
141 		void setInstanceID(int instanceID);
142 
143 		void setTextureFilter(unsigned int sampler, FilterType textureFilter);
144 		void setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter);
145 		void setGatherEnable(unsigned int sampler, bool enable);
146 		void setAddressingModeU(unsigned int sampler, AddressingMode addressingMode);
147 		void setAddressingModeV(unsigned int sampler, AddressingMode addressingMode);
148 		void setAddressingModeW(unsigned int sampler, AddressingMode addressingMode);
149 		void setReadSRGB(unsigned int sampler, bool sRGB);
150 		void setMipmapLOD(unsigned int sampler, float bias);
151 		void setBorderColor(unsigned int sampler, const Color<float> &borderColor);
152 		void setMaxAnisotropy(unsigned int stage, float maxAnisotropy);
153 		void setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering);
154 		void setSwizzleR(unsigned int sampler, SwizzleType swizzleR);
155 		void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
156 		void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
157 		void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
158 		void setCompareFunc(unsigned int sampler, CompareFunc compare);
159 		void setBaseLevel(unsigned int sampler, int baseLevel);
160 		void setMaxLevel(unsigned int sampler, int maxLevel);
161 		void setMinLod(unsigned int sampler, float minLod);
162 		void setMaxLod(unsigned int sampler, float maxLod);
163 
164 		void setPointSizeMin(float pointSizeMin);
165 		void setPointSizeMax(float pointSizeMax);
166 
167 		void setTransformFeedbackQueryEnabled(bool enable);
168 		void enableTransformFeedback(uint64_t enable);
169 
170 	protected:
171 		const State update(DrawType drawType);
172 		Routine *routine(const State &state);
173 
174 		void setRoutineCacheSize(int cacheSize);
175 
176 		// Shader constants
177 		float4 c[VERTEX_UNIFORM_VECTORS + 1];   // One extra for indices out of range, c[VERTEX_UNIFORM_VECTORS] = {0, 0, 0, 0}
178 		int4 i[16];
179 		bool b[16];
180 
181 		float pointSizeMin;
182 		float pointSizeMax;
183 
184 	private:
185 		struct UniformBufferInfo
186 		{
187 			UniformBufferInfo();
188 
189 			Resource* buffer;
190 			int offset;
191 		};
192 		UniformBufferInfo uniformBufferInfo[MAX_UNIFORM_BUFFER_BINDINGS];
193 
194 		struct TransformFeedbackInfo
195 		{
196 			TransformFeedbackInfo();
197 
198 			Resource* buffer;
199 			unsigned int offset;
200 			unsigned int reg;
201 			unsigned int row;
202 			unsigned int col;
203 			unsigned int stride;
204 		};
205 		TransformFeedbackInfo transformFeedbackInfo[MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS];
206 
207 		Context *const context;
208 
209 		RoutineCache<State> *routineCache;
210 	};
211 }
212 
213 #endif   // sw_VertexProcessor_hpp
214