• 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 "Primitive.hpp"
21 #include "SetupProcessor.hpp"
22 #include "VertexProcessor.hpp"
23 #include "Vulkan/VkDescriptorSet.hpp"
24 #include "Vulkan/VkPipeline.hpp"
25 
26 #include "marl/finally.h"
27 #include "marl/pool.h"
28 #include "marl/ticket.h"
29 
30 #include <atomic>
31 #include <list>
32 #include <mutex>
33 #include <thread>
34 
35 namespace vk {
36 
37 class DescriptorSet;
38 class Device;
39 class Query;
40 class PipelineLayout;
41 
42 }  // namespace vk
43 
44 namespace sw {
45 
46 class CountedEvent;
47 struct DrawCall;
48 class PixelShader;
49 class VertexShader;
50 struct Task;
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 depthRange;
91 	float depthNear;
92 	float minimumResolvableDepthDifference;
93 	float constantDepthBias;
94 	float slopeDepthBias;
95 	float depthBiasClamp;
96 
97 	unsigned int *colorBuffer[RENDERTARGETS];
98 	int colorPitchB[RENDERTARGETS];
99 	int colorSliceB[RENDERTARGETS];
100 	float *depthBuffer;
101 	int depthPitchB;
102 	int depthSliceB;
103 	unsigned char *stencilBuffer;
104 	int stencilPitchB;
105 	int stencilSliceB;
106 
107 	int scissorX0;
108 	int scissorX1;
109 	int scissorY0;
110 	int scissorY1;
111 
112 	float4 a2c0;
113 	float4 a2c1;
114 	float4 a2c2;
115 	float4 a2c3;
116 
117 	vk::Pipeline::PushConstantStorage pushConstants;
118 };
119 
120 struct DrawCall
121 {
122 	struct BatchData
123 	{
124 		using Pool = marl::BoundedPool<BatchData, MaxBatchCount, marl::PoolPolicy::Preserve>;
125 
126 		TriangleBatch triangles;
127 		PrimitiveBatch primitives;
128 		VertexTask vertexTask;
129 		unsigned int id;
130 		unsigned int firstPrimitive;
131 		unsigned int numPrimitives;
132 		int numVisible;
133 		marl::Ticket clusterTickets[MaxClusterCount];
134 	};
135 
136 	using Pool = marl::BoundedPool<DrawCall, MaxDrawCount, marl::PoolPolicy::Preserve>;
137 	using SetupFunction = int (*)(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
138 
139 	DrawCall();
140 	~DrawCall();
141 
142 	static void run(const marl::Loan<DrawCall> &draw, marl::Ticket::Queue *tickets, marl::Ticket::Queue clusterQueues[MaxClusterCount]);
143 	static void processVertices(DrawCall *draw, BatchData *batch);
144 	static void processPrimitives(DrawCall *draw, BatchData *batch);
145 	static void processPixels(const marl::Loan<DrawCall> &draw, const marl::Loan<BatchData> &batch, const std::shared_ptr<marl::Finally> &finally);
146 	void setup();
147 	void teardown();
148 
149 	int id;
150 
151 	BatchData::Pool *batchDataPool;
152 	unsigned int numPrimitives;
153 	unsigned int numPrimitivesPerBatch;
154 	unsigned int numBatches;
155 
156 	VkPrimitiveTopology topology;
157 	VkProvokingVertexModeEXT provokingVertexMode;
158 	VkIndexType indexType;
159 	VkLineRasterizationModeEXT lineRasterizationMode;
160 
161 	VertexProcessor::RoutineType vertexRoutine;
162 	SetupProcessor::RoutineType setupRoutine;
163 	PixelProcessor::RoutineType pixelRoutine;
164 	bool containsImageWrite;
165 
166 	SetupFunction setupPrimitives;
167 	SetupProcessor::State setupState;
168 
169 	vk::Device *device;
170 	vk::ImageView *renderTarget[RENDERTARGETS];
171 	vk::ImageView *depthBuffer;
172 	vk::ImageView *stencilBuffer;
173 	vk::DescriptorSet::Array descriptorSetObjects;
174 	const vk::PipelineLayout *pipelineLayout;
175 	sw::CountedEvent *events;
176 
177 	vk::Query *occlusionQuery;
178 
179 	DrawData *data;
180 
181 	static void processPrimitiveVertices(
182 	    unsigned int triangleIndicesOut[MaxBatchSize + 1][3],
183 	    const void *primitiveIndices,
184 	    VkIndexType indexType,
185 	    unsigned int start,
186 	    unsigned int triangleCount,
187 	    VkPrimitiveTopology topology,
188 	    VkProvokingVertexModeEXT provokingVertexMode);
189 
190 	static int setupSolidTriangles(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
191 	static int setupWireframeTriangles(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
192 	static int setupPointTriangles(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
193 	static int setupLines(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
194 	static int setupPoints(Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count);
195 
196 	static bool setupLine(Primitive &primitive, Triangle &triangle, const DrawCall &draw);
197 	static bool setupPoint(Primitive &primitive, Triangle &triangle, const DrawCall &draw);
198 };
199 
200 class alignas(16) Renderer
201 {
202 public:
203 	Renderer(vk::Device *device);
204 
205 	virtual ~Renderer();
206 
207 	void *operator new(size_t size);
208 	void operator delete(void *mem);
209 
hasOcclusionQuery() const210 	bool hasOcclusionQuery() const { return occlusionQuery != nullptr; }
211 
212 	void draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState &dynamicState, unsigned int count, int baseVertex,
213 	          CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D &framebufferExtent,
214 	          vk::Pipeline::PushConstantStorage const &pushConstants, bool update = true);
215 
216 	void addQuery(vk::Query *query);
217 	void removeQuery(vk::Query *query);
218 
219 	void synchronize();
220 
221 private:
222 	DrawCall::Pool drawCallPool;
223 	DrawCall::BatchData::Pool batchDataPool;
224 
225 	std::atomic<int> nextDrawID = { 0 };
226 
227 	vk::Query *occlusionQuery = nullptr;
228 	marl::Ticket::Queue drawTickets;
229 	marl::Ticket::Queue clusterQueues[MaxClusterCount];
230 
231 	VertexProcessor vertexProcessor;
232 	PixelProcessor pixelProcessor;
233 	SetupProcessor setupProcessor;
234 
235 	VertexProcessor::State vertexState;
236 	SetupProcessor::State setupState;
237 	PixelProcessor::State pixelState;
238 
239 	VertexProcessor::RoutineType vertexRoutine;
240 	SetupProcessor::RoutineType setupRoutine;
241 	PixelProcessor::RoutineType pixelRoutine;
242 
243 	vk::Device *device;
244 };
245 
246 }  // namespace sw
247 
248 #endif  // sw_Renderer_hpp
249