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