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