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 vk::DescriptorSet::Bindings descriptorSets = {}; 65 vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {}; 66 67 const void *input[MAX_INTERFACE_COMPONENTS / 4]; 68 unsigned int robustnessSize[MAX_INTERFACE_COMPONENTS / 4]; 69 unsigned int stride[MAX_INTERFACE_COMPONENTS / 4]; 70 const void *indices; 71 72 int instanceID; 73 int baseVertex; 74 float lineWidth; 75 int viewID; 76 77 PixelProcessor::Stencil stencil[2]; // clockwise, counterclockwise 78 PixelProcessor::Factor factor; 79 unsigned int occlusion[MaxClusterCount]; // Number of pixels passing depth test 80 81 float4 WxF; 82 float4 HxF; 83 float4 X0xF; 84 float4 Y0xF; 85 float4 halfPixelX; 86 float4 halfPixelY; 87 float viewportHeight; 88 float depthRange; 89 float depthNear; 90 float minimumResolvableDepthDifference; 91 float constantDepthBias; 92 float slopeDepthBias; 93 float depthBiasClamp; 94 bool depthClipEnable; 95 96 unsigned int *colorBuffer[MAX_COLOR_BUFFERS]; 97 int colorPitchB[MAX_COLOR_BUFFERS]; 98 int colorSliceB[MAX_COLOR_BUFFERS]; 99 float *depthBuffer; 100 int depthPitchB; 101 int depthSliceB; 102 unsigned char *stencilBuffer; 103 int stencilPitchB; 104 int stencilSliceB; 105 106 int scissorX0; 107 int scissorX1; 108 int scissorY0; 109 int scissorY1; 110 111 float4 a2c0; 112 float4 a2c1; 113 float4 a2c2; 114 float4 a2c3; 115 116 vk::Pipeline::PushConstantStorage pushConstants; 117 }; 118 119 struct DrawCall 120 { 121 struct BatchData 122 { 123 using Pool = marl::BoundedPool<BatchData, MaxBatchCount, marl::PoolPolicy::Preserve>; 124 125 TriangleBatch triangles; 126 PrimitiveBatch primitives; 127 VertexTask vertexTask; 128 unsigned int id; 129 unsigned int firstPrimitive; 130 unsigned int numPrimitives; 131 int numVisible; 132 marl::Ticket clusterTickets[MaxClusterCount]; 133 }; 134 135 using Pool = marl::BoundedPool<DrawCall, MaxDrawCount, marl::PoolPolicy::Preserve>; 136 using SetupFunction = int (*)(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 137 138 DrawCall(); 139 ~DrawCall(); 140 141 static void run(vk::Device *device, const marl::Loan<DrawCall> &draw, marl::Ticket::Queue *tickets, marl::Ticket::Queue clusterQueues[MaxClusterCount]); 142 static void processVertices(vk::Device *device, DrawCall *draw, BatchData *batch); 143 static void processPrimitives(vk::Device *device, DrawCall *draw, BatchData *batch); 144 static void processPixels(vk::Device *device, const marl::Loan<DrawCall> &draw, const marl::Loan<BatchData> &batch, const std::shared_ptr<marl::Finally> &finally); 145 void setup(); 146 void teardown(vk::Device *device); 147 148 int id; 149 150 BatchData::Pool *batchDataPool; 151 unsigned int numPrimitives; 152 unsigned int numPrimitivesPerBatch; 153 unsigned int numBatches; 154 155 VkPrimitiveTopology topology; 156 VkProvokingVertexModeEXT provokingVertexMode; 157 VkIndexType indexType; 158 VkLineRasterizationModeEXT lineRasterizationMode; 159 160 bool depthClipEnable; 161 162 VertexProcessor::RoutineType vertexRoutine; 163 SetupProcessor::RoutineType setupRoutine; 164 PixelProcessor::RoutineType pixelRoutine; 165 bool containsImageWrite; 166 167 SetupFunction setupPrimitives; 168 SetupProcessor::State setupState; 169 170 vk::ImageView *colorBuffer[MAX_COLOR_BUFFERS]; 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(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 191 static int setupWireframeTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 192 static int setupPointTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 193 static int setupLines(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 194 static int setupPoints(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 195 196 static bool setupLine(vk::Device *device, Primitive &primitive, Triangle &triangle, const DrawCall &draw); 197 static bool setupPoint(vk::Device *device, 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