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