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 float4 WxF; 78 float4 HxF; 79 float4 X0xF; 80 float4 Y0xF; 81 float4 halfPixelX; 82 float4 halfPixelY; 83 float viewportHeight; 84 float depthRange; 85 float depthNear; 86 float minimumResolvableDepthDifference; 87 float constantDepthBias; 88 float slopeDepthBias; 89 float depthBiasClamp; 90 bool depthClipEnable; 91 92 unsigned int *colorBuffer[MAX_COLOR_BUFFERS]; 93 int colorPitchB[MAX_COLOR_BUFFERS]; 94 int colorSliceB[MAX_COLOR_BUFFERS]; 95 float *depthBuffer; 96 int depthPitchB; 97 int depthSliceB; 98 unsigned char *stencilBuffer; 99 int stencilPitchB; 100 int stencilSliceB; 101 102 int scissorX0; 103 int scissorX1; 104 int scissorY0; 105 int scissorY1; 106 107 float4 a2c0; 108 float4 a2c1; 109 float4 a2c2; 110 float4 a2c3; 111 112 vk::Pipeline::PushConstantStorage pushConstants; 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 158 VertexProcessor::RoutineType vertexRoutine; 159 SetupProcessor::RoutineType setupRoutine; 160 PixelProcessor::RoutineType pixelRoutine; 161 bool containsImageWrite; 162 163 SetupFunction setupPrimitives; 164 SetupProcessor::State setupState; 165 166 vk::ImageView *colorBuffer[MAX_COLOR_BUFFERS]; 167 vk::ImageView *depthBuffer; 168 vk::ImageView *stencilBuffer; 169 vk::DescriptorSet::Array descriptorSetObjects; 170 const vk::PipelineLayout *pipelineLayout; 171 sw::CountedEvent *events; 172 173 vk::Query *occlusionQuery; 174 175 DrawData *data; 176 177 static void processPrimitiveVertices( 178 unsigned int triangleIndicesOut[MaxBatchSize + 1][3], 179 const void *primitiveIndices, 180 VkIndexType indexType, 181 unsigned int start, 182 unsigned int triangleCount, 183 VkPrimitiveTopology topology, 184 VkProvokingVertexModeEXT provokingVertexMode); 185 186 static int setupSolidTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 187 static int setupWireframeTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 188 static int setupPointTriangles(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 189 static int setupLines(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 190 static int setupPoints(vk::Device *device, Triangle *triangles, Primitive *primitives, const DrawCall *drawCall, int count); 191 192 static bool setupLine(vk::Device *device, Primitive &primitive, Triangle &triangle, const DrawCall &draw); 193 static bool setupPoint(vk::Device *device, Primitive &primitive, Triangle &triangle, const DrawCall &draw); 194 }; 195 196 class alignas(16) Renderer 197 { 198 public: 199 Renderer(vk::Device *device); 200 201 virtual ~Renderer(); 202 203 void *operator new(size_t size); 204 void operator delete(void *mem); 205 hasOcclusionQuery() const206 bool hasOcclusionQuery() const { return occlusionQuery != nullptr; } 207 208 void draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState &dynamicState, unsigned int count, int baseVertex, 209 CountedEvent *events, int instanceID, int layer, void *indexBuffer, const VkRect2D &renderArea, 210 vk::Pipeline::PushConstantStorage const &pushConstants, bool update = true); 211 212 void addQuery(vk::Query *query); 213 void removeQuery(vk::Query *query); 214 215 void synchronize(); 216 217 private: 218 DrawCall::Pool drawCallPool; 219 DrawCall::BatchData::Pool batchDataPool; 220 221 std::atomic<int> nextDrawID = { 0 }; 222 223 vk::Query *occlusionQuery = nullptr; 224 marl::Ticket::Queue drawTickets; 225 marl::Ticket::Queue clusterQueues[MaxClusterCount]; 226 227 VertexProcessor vertexProcessor; 228 PixelProcessor pixelProcessor; 229 SetupProcessor setupProcessor; 230 231 VertexProcessor::State vertexState; 232 SetupProcessor::State setupState; 233 PixelProcessor::State pixelState; 234 235 VertexProcessor::RoutineType vertexRoutine; 236 SetupProcessor::RoutineType setupRoutine; 237 PixelProcessor::RoutineType pixelRoutine; 238 239 vk::Device *device; 240 }; 241 242 } // namespace sw 243 244 #endif // sw_Renderer_hpp 245