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 bool useCompareMask; 47 bool useWriteMask; 48 bool writeEnabled; 49 operator =sw::PixelProcessor::States::StencilOpState50 void operator=(const VkStencilOpState &rhs) 51 { 52 failOp = rhs.failOp; 53 passOp = rhs.passOp; 54 depthFailOp = rhs.depthFailOp; 55 compareOp = rhs.compareOp; 56 useCompareMask = (rhs.compareMask != 0xff); 57 useWriteMask = ((rhs.writeMask & 0xFF) != 0xFF); 58 writeEnabled = (rhs.writeMask != 0); 59 } 60 }; 61 Statessw::PixelProcessor::States62 States() 63 : Memset(this, 0) 64 {} 65 66 uint32_t computeHash(); 67 68 uint64_t shaderID; 69 uint32_t pipelineLayoutIdentifier; 70 71 unsigned int numClipDistances; 72 unsigned int numCullDistances; 73 74 VkCompareOp depthCompareMode; 75 bool depthWriteEnable; 76 77 bool robustBufferAccess; 78 79 bool stencilActive; 80 StencilOpState frontStencil; 81 StencilOpState backStencil; 82 83 bool depthTestActive; 84 bool depthBoundsTestActive; 85 bool occlusionEnabled; 86 bool perspective; 87 88 vk::BlendState blendState[MAX_COLOR_BUFFERS]; 89 90 unsigned int colorWriteMask; 91 vk::Format colorFormat[MAX_COLOR_BUFFERS]; 92 unsigned int multiSampleCount; 93 unsigned int multiSampleMask; 94 bool enableMultiSampling; 95 bool alphaToCoverage; 96 bool centroid; 97 bool sampleShadingEnabled; 98 float minSampleShading; 99 float minDepthBounds; 100 float maxDepthBounds; 101 VkFrontFace frontFace; 102 vk::Format depthFormat; 103 bool depthBias; 104 bool depthClamp; 105 106 float minDepthClamp; 107 float maxDepthClamp; 108 }; 109 110 struct State : States 111 { 112 bool operator==(const State &state) const; 113 colorWriteActivesw::PixelProcessor::State114 int colorWriteActive(int index) const 115 { 116 return (colorWriteMask >> (index * 4)) & 0xF; 117 } 118 119 uint32_t hash; 120 }; 121 122 struct Stencil 123 { 124 int64_t testMaskQ; 125 int64_t referenceMaskedQ; 126 int64_t referenceMaskedSignedQ; 127 int64_t writeMaskQ; 128 int64_t invWriteMaskQ; 129 int64_t referenceQ; 130 setsw::PixelProcessor::Stencil131 void set(int reference, int testMask, int writeMask) 132 { 133 referenceQ = replicate(reference); 134 testMaskQ = replicate(testMask); 135 writeMaskQ = replicate(writeMask); 136 invWriteMaskQ = ~writeMaskQ; 137 referenceMaskedQ = referenceQ & testMaskQ; 138 referenceMaskedSignedQ = replicate(((reference & testMask) + 0x80) & 0xFF); 139 } 140 replicatesw::PixelProcessor::Stencil141 static int64_t replicate(int b) 142 { 143 int64_t w = b & 0xFF; 144 145 return (w << 0) | (w << 8) | (w << 16) | (w << 24) | (w << 32) | (w << 40) | (w << 48) | (w << 56); 146 } 147 }; 148 149 struct Factor 150 { 151 float4 blendConstantF; // Unclamped for floating-point attachment formats. 152 float4 invBlendConstantF; // Unclamped for floating-point attachment formats. 153 float4 blendConstantU; // Clamped to [0,1] for unsigned fixed-point attachment formats. 154 float4 invBlendConstantU; // Clamped to [0,1] for unsigned fixed-point attachment formats. 155 float4 blendConstantS; // Clamped to [-1,1] for signed fixed-point attachment formats. 156 float4 invBlendConstantS; // Clamped to [-1,1] for signed fixed-point attachment formats. 157 }; 158 159 public: 160 using RoutineType = RasterizerFunction::RoutineType; 161 162 PixelProcessor(); 163 164 void setBlendConstant(const float4 &blendConstant); 165 166 const State update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *fragmentShader, const sw::SpirvShader *vertexShader, const vk::Attachments &attachments, bool occlusionEnabled) const; 167 RoutineType routine(const State &state, const vk::PipelineLayout *pipelineLayout, 168 const SpirvShader *pixelShader, const vk::Attachments &attachments, const vk::DescriptorSet::Bindings &descriptorSets); 169 void setRoutineCacheSize(int routineCacheSize); 170 171 // Other semi-constants 172 Factor factor; 173 174 private: 175 using RoutineCacheType = RoutineCache<State, RasterizerFunction::CFunctionType>; 176 std::unique_ptr<RoutineCacheType> routineCache; 177 }; 178 179 } // namespace sw 180 181 namespace std { 182 183 template<> 184 struct hash<sw::PixelProcessor::State> 185 { operator ()std::hash186 uint64_t operator()(const sw::PixelProcessor::State &state) const 187 { 188 return state.hash; 189 } 190 }; 191 192 } // namespace std 193 194 #endif // sw_PixelProcessor_hpp 195