• 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_Renderer_hpp
16 #define sw_Renderer_hpp
17 
18 #include "PixelProcessor.hpp"
19 #include "Primitive.hpp"
20 #include "SetupProcessor.hpp"
21 #include "VertexProcessor.hpp"
22 #include "Vulkan/VkDescriptorSet.hpp"
23 #include "Vulkan/VkPipeline.hpp"
24 
25 #include "marl/finally.h"
26 #include "marl/pool.h"
27 #include "marl/ticket.h"
28 
29 #include <atomic>
30 
31 namespace vk {
32 
33 class DescriptorSet;
34 class Device;
35 class Query;
36 class PipelineLayout;
37 
38 }  // namespace vk
39 
40 namespace sw {
41 
42 class CountedEvent;
43 struct DrawCall;
44 class PixelShader;
45 class VertexShader;
46 struct Task;
47 class Resource;
48 struct Constants;
49 
50 static constexpr int MaxBatchSize = 128;
51 static constexpr int MaxBatchCount = 16;
52 static constexpr int MaxClusterCount = 16;
53 static constexpr int MaxDrawCount = 16;
54 
55 using TriangleBatch = std::array<Triangle, MaxBatchSize>;
56 using PrimitiveBatch = std::array<Primitive, MaxBatchSize>;
57 
58 struct DrawData
59 {
60 	vk::DescriptorSet::Bindings descriptorSets = {};
61 	vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
62 
63 	const void *input[MAX_INTERFACE_COMPONENTS / 4];
64 	unsigned int robustnessSize[MAX_INTERFACE_COMPONENTS / 4];
65 	unsigned int stride[MAX_INTERFACE_COMPONENTS / 4];
66 	const void *indices;
67 
68 	int instanceID;
69 	int baseVertex;
70 	float lineWidth;
71 	int layer;
72 
73 	PixelProcessor::Stencil stencil[2];  // clockwise, counterclockwise
74 	PixelProcessor::Factor factor;
75 	unsigned int occlusion[MaxClusterCount];  // Number of pixels passing depth test
76 
77 	float4 WxF;
78 	float4 HxF;
79 	float4 X0xF;
80 	float4 Y0xF;
81 	float4 halfPixelX;
82 	float4 halfPixelY;
83 	float viewportHeight;
84 	float depthRange;
85 	float depthNear;
86 	float minimumResolvableDepthDifference;
87 	float constantDepthBias;
88 	float slopeDepthBias;
89 	float depthBiasClamp;
90 	bool depthClipEnable;
91 
92 	unsigned int *colorBuffer[MAX_COLOR_BUFFERS];
93 	int colorPitchB[MAX_COLOR_BUFFERS];
94 	int colorSliceB[MAX_COLOR_BUFFERS];
95 	float *depthBuffer;
96 	int depthPitchB;
97 	int depthSliceB;
98 	unsigned char *stencilBuffer;
99 	int stencilPitchB;
100 	int stencilSliceB;
101 
102 	int scissorX0;
103 	int scissorX1;
104 	int scissorY0;
105 	int scissorY1;
106 
107 	float4 a2c0;
108 	float4 a2c1;
109 	float4 a2c2;
110 	float4 a2c3;
111 
112 	vk::Pipeline::PushConstantStorage pushConstants;
113 };
114 
115 struct DrawCall
116 {
117 	struct BatchData
118 	{
119 		using Pool = marl::BoundedPool<BatchData, MaxBatchCount, marl::PoolPolicy::Preserve>;
120 
121 		TriangleBatch triangles;
122 		PrimitiveBatch primitives;
123 		VertexTask vertexTask;
124 		unsigned int id;
125 		unsigned int firstPrimitive;
126 		unsigned int numPrimitives;
127 		int numVisible;
128 		marl::Ticket clusterTickets[MaxClusterCount];
129 	};
130 
131 	using Pool = marl::BoundedPool<DrawCall, MaxDrawCount, marl::PoolPolicy::Preserve>;
132 	using SetupFunction = int (*)(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
133 
134 	DrawCall();
135 	~DrawCall();
136 
137 	static void run(vk::Device *device, const marl::Loan<DrawCall> &draw, marl::Ticket::Queue *tickets, marl::Ticket::Queue clusterQueues[MaxClusterCount]);
138 	static void processVertices(vk::Device *device, DrawCall *draw, BatchData *batch);
139 	static void processPrimitives(vk::Device *device, DrawCall *draw, BatchData *batch);
140 	static void processPixels(vk::Device *device, const marl::Loan<DrawCall> &draw, const marl::Loan<BatchData> &batch, const std::shared_ptr<marl::Finally> &finally);
141 	void setup();
142 	void teardown(vk::Device *device);
143 
144 	int id;
145 
146 	BatchData::Pool *batchDataPool;
147 	unsigned int numPrimitives;
148 	unsigned int numPrimitivesPerBatch;
149 	unsigned int numBatches;
150 
151 	VkPrimitiveTopology topology;
152 	VkProvokingVertexModeEXT provokingVertexMode;
153 	VkIndexType indexType;
154 	VkLineRasterizationModeEXT lineRasterizationMode;
155 
156 	bool depthClipEnable;
157 
158 	VertexProcessor::RoutineType vertexRoutine;
159 	SetupProcessor::RoutineType setupRoutine;
160 	PixelProcessor::RoutineType pixelRoutine;
161 	bool containsImageWrite;
162 
163 	SetupFunction setupPrimitives;
164 	SetupProcessor::State setupState;
165 
166 	vk::ImageView *colorBuffer[MAX_COLOR_BUFFERS];
167 	vk::ImageView *depthBuffer;
168 	vk::ImageView *stencilBuffer;
169 	vk::DescriptorSet::Array descriptorSetObjects;
170 	const vk::PipelineLayout *pipelineLayout;
171 	sw::CountedEvent *events;
172 
173 	vk::Query *occlusionQuery;
174 
175 	DrawData *data;
176 
177 	static void processPrimitiveVertices(
178 	    unsigned int triangleIndicesOut[MaxBatchSize + 1][3],
179 	    const void *primitiveIndices,
180 	    VkIndexType indexType,
181 	    unsigned int start,
182 	    unsigned int triangleCount,
183 	    VkPrimitiveTopology topology,
184 	    VkProvokingVertexModeEXT provokingVertexMode);
185 
186 	static int setupSolidTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
187 	static int setupWireframeTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
188 	static int setupPointTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
189 	static int setupLines(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
190 	static int setupPoints(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
191 
192 	static bool setupLine(vk::Device *device, Primitive &primitive, Triangle &triangle, const DrawCall &draw);
193 	static bool setupPoint(vk::Device *device, Primitive &primitive, Triangle &triangle, const DrawCall &draw);
194 };
195 
196 class alignas(16) Renderer
197 {
198 public:
199 	Renderer(vk::Device *device);
200 
201 	virtual ~Renderer();
202 
203 	void *operator new(size_t size);
204 	void operator delete(void *mem);
205 
hasOcclusionQuery() const206 	bool hasOcclusionQuery() const { return occlusionQuery != nullptr; }
207 
208 	void draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState &dynamicState, unsigned int count, int baseVertex,
209 	          CountedEvent *events, int instanceID, int layer, void *indexBuffer, const VkRect2D &renderArea,
210 	          vk::Pipeline::PushConstantStorage const &pushConstants, bool update = true);
211 
212 	void addQuery(vk::Query *query);
213 	void removeQuery(vk::Query *query);
214 
215 	void synchronize();
216 
217 private:
218 	DrawCall::Pool drawCallPool;
219 	DrawCall::BatchData::Pool batchDataPool;
220 
221 	std::atomic<int> nextDrawID = { 0 };
222 
223 	vk::Query *occlusionQuery = nullptr;
224 	marl::Ticket::Queue drawTickets;
225 	marl::Ticket::Queue clusterQueues[MaxClusterCount];
226 
227 	VertexProcessor vertexProcessor;
228 	PixelProcessor pixelProcessor;
229 	SetupProcessor setupProcessor;
230 
231 	VertexProcessor::State vertexState;
232 	SetupProcessor::State setupState;
233 	PixelProcessor::State pixelState;
234 
235 	VertexProcessor::RoutineType vertexRoutine;
236 	SetupProcessor::RoutineType setupRoutine;
237 	PixelProcessor::RoutineType pixelRoutine;
238 
239 	vk::Device *device;
240 };
241 
242 }  // namespace sw
243 
244 #endif  // sw_Renderer_hpp
245