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