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_PixelProcessor_hpp 16 #define sw_PixelProcessor_hpp 17 18 #include "Context.hpp" 19 #include "Memset.hpp" 20 #include "RoutineCache.hpp" 21 #include "Vulkan/VkFormat.hpp" 22 23 #include <memory> 24 25 namespace sw { 26 27 struct DrawData; 28 struct Primitive; 29 class SpirvShader; 30 31 using RasterizerFunction = FunctionT<void(const vk::Device *device, const Primitive *primitive, int count, int cluster, int clusterCount, DrawData *draw)>; 32 33 class PixelProcessor 34 { 35 public: 36 struct States : Memset<States> 37 { 38 // Same as VkStencilOpState, but with no reference, as it's not part of the state 39 // (it doesn't require a different program to be generated) 40 struct StencilOpState 41 { 42 VkStencilOp failOp; 43 VkStencilOp passOp; 44 VkStencilOp depthFailOp; 45 VkCompareOp compareOp; 46 uint32_t compareMask; 47 uint32_t writeMask; 48 operator =sw::PixelProcessor::States::StencilOpState49 void operator=(const VkStencilOpState &rhs) 50 { 51 failOp = rhs.failOp; 52 passOp = rhs.passOp; 53 depthFailOp = rhs.depthFailOp; 54 compareOp = rhs.compareOp; 55 compareMask = rhs.compareMask; 56 writeMask = rhs.writeMask; 57 } 58 }; 59 Statessw::PixelProcessor::States60 States() 61 : Memset(this, 0) 62 {} 63 64 uint32_t computeHash(); 65 66 uint64_t shaderID; 67 uint32_t pipelineLayoutIdentifier; 68 69 unsigned int numClipDistances; 70 unsigned int numCullDistances; 71 72 VkCompareOp depthCompareMode; 73 bool depthWriteEnable; 74 75 bool stencilActive; 76 StencilOpState frontStencil; 77 StencilOpState backStencil; 78 79 bool depthTestActive; 80 bool depthBoundsTestActive; 81 bool occlusionEnabled; 82 bool perspective; 83 84 vk::BlendState blendState[MAX_COLOR_BUFFERS]; 85 86 unsigned int colorWriteMask; 87 vk::Format colorFormat[MAX_COLOR_BUFFERS]; 88 unsigned int multiSampleCount; 89 unsigned int multiSampleMask; 90 bool enableMultiSampling; 91 bool alphaToCoverage; 92 bool centroid; 93 bool sampleShadingEnabled; 94 float minSampleShading; 95 float minDepthBounds; 96 float maxDepthBounds; 97 VkFrontFace frontFace; 98 vk::Format depthFormat; 99 bool depthBias; 100 bool depthClamp; 101 102 float minDepthClamp; 103 float maxDepthClamp; 104 }; 105 106 struct State : States 107 { 108 bool operator==(const State &state) const; 109 colorWriteActivesw::PixelProcessor::State110 int colorWriteActive(int index) const 111 { 112 return (colorWriteMask >> (index * 4)) & 0xF; 113 } 114 115 uint32_t hash; 116 }; 117 118 struct Stencil 119 { 120 int64_t testMaskQ; 121 int64_t referenceMaskedQ; 122 int64_t referenceMaskedSignedQ; 123 int64_t writeMaskQ; 124 int64_t invWriteMaskQ; 125 int64_t referenceQ; 126 setsw::PixelProcessor::Stencil127 void set(int reference, int testMask, int writeMask) 128 { 129 referenceQ = replicate(reference); 130 testMaskQ = replicate(testMask); 131 writeMaskQ = replicate(writeMask); 132 invWriteMaskQ = ~writeMaskQ; 133 referenceMaskedQ = referenceQ & testMaskQ; 134 referenceMaskedSignedQ = replicate(((reference & testMask) + 0x80) & 0xFF); 135 } 136 replicatesw::PixelProcessor::Stencil137 static int64_t replicate(int b) 138 { 139 int64_t w = b & 0xFF; 140 141 return (w << 0) | (w << 8) | (w << 16) | (w << 24) | (w << 32) | (w << 40) | (w << 48) | (w << 56); 142 } 143 }; 144 145 struct Factor 146 { 147 float4 blendConstantF; // Unclamped for floating-point attachment formats. 148 float4 invBlendConstantF; // Unclamped for floating-point attachment formats. 149 float4 blendConstantU; // Clamped to [0,1] for unsigned fixed-point attachment formats. 150 float4 invBlendConstantU; // Clamped to [0,1] for unsigned fixed-point attachment formats. 151 float4 blendConstantS; // Clamped to [-1,1] for signed fixed-point attachment formats. 152 float4 invBlendConstantS; // Clamped to [-1,1] for signed fixed-point attachment formats. 153 }; 154 155 public: 156 using RoutineType = RasterizerFunction::RoutineType; 157 158 PixelProcessor(); 159 160 void setBlendConstant(const float4 &blendConstant); 161 162 const State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *fragmentShader, const sw::SpirvShader *vertexShader, const vk::Attachments &attachments, bool occlusionEnabled) const; 163 RoutineType routine(const State &state, const vk::PipelineLayout *pipelineLayout, 164 const SpirvShader *pixelShader, const vk::DescriptorSet::Bindings &descriptorSets); 165 void setRoutineCacheSize(int routineCacheSize); 166 167 // Other semi-constants 168 Factor factor; 169 170 private: 171 using RoutineCacheType = RoutineCache<State, RasterizerFunction::CFunctionType>; 172 std::unique_ptr<RoutineCacheType> routineCache; 173 }; 174 175 } // namespace sw 176 177 namespace std { 178 179 template<> 180 struct hash<sw::PixelProcessor::State> 181 { operator ()std::hash182 uint64_t operator()(const sw::PixelProcessor::State &state) const 183 { 184 return state.hash; 185 } 186 }; 187 188 } // namespace std 189 190 #endif // sw_PixelProcessor_hpp 191