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