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 | |
36 | namespace vk |
37 | { |
38 | class DescriptorSet; |
39 | class Device; |
40 | class Query; |
41 | } |
42 | |
43 | namespace 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 | |