|  | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | #ifndef sw_PixelProcessor_hpp | 
|  | #define sw_PixelProcessor_hpp | 
|  |  | 
|  | #include "Color.hpp" | 
|  | #include "Context.hpp" | 
|  | #include "Memset.hpp" | 
|  | #include "RoutineCache.hpp" | 
|  |  | 
|  | namespace sw | 
|  | { | 
|  | class PixelShader; | 
|  | class Rasterizer; | 
|  | struct Texture; | 
|  | struct DrawData; | 
|  | struct Primitive; | 
|  |  | 
|  | using RasterizerFunction = FunctionT<void(const Primitive* primitive, int count, int cluster, int clusterCount, DrawData* draw)>; | 
|  |  | 
|  | class PixelProcessor | 
|  | { | 
|  | public: | 
|  | struct States : Memset<States> | 
|  | { | 
|  | // Same as VkStencilOpState, but with no reference, as it's not part of the state | 
|  | // (it doesn't require a different program to be generated) | 
|  | struct StencilOpState | 
|  | { | 
|  | VkStencilOp    failOp; | 
|  | VkStencilOp    passOp; | 
|  | VkStencilOp    depthFailOp; | 
|  | VkCompareOp    compareOp; | 
|  | uint32_t       compareMask; | 
|  | uint32_t       writeMask; | 
|  |  | 
|  | void operator=(const VkStencilOpState &rhs) | 
|  | { | 
|  | failOp = rhs.failOp; | 
|  | passOp = rhs.passOp; | 
|  | depthFailOp = rhs.depthFailOp; | 
|  | compareOp = rhs.compareOp; | 
|  | compareMask = rhs.compareMask; | 
|  | writeMask = rhs.writeMask; | 
|  | } | 
|  | }; | 
|  |  | 
|  | States() : Memset(this, 0) {} | 
|  |  | 
|  | uint32_t computeHash(); | 
|  |  | 
|  | uint64_t shaderID; | 
|  |  | 
|  | VkCompareOp depthCompareMode; | 
|  | bool depthWriteEnable; | 
|  |  | 
|  | bool stencilActive; | 
|  | StencilOpState frontStencil; | 
|  | StencilOpState backStencil; | 
|  |  | 
|  | bool depthTestActive; | 
|  | bool occlusionEnabled; | 
|  | bool perspective; | 
|  | bool depthClamp; | 
|  |  | 
|  | BlendState blendState[RENDERTARGETS]; | 
|  |  | 
|  | unsigned int colorWriteMask; | 
|  | VkFormat targetFormat[RENDERTARGETS]; | 
|  | unsigned int multiSample; | 
|  | unsigned int multiSampleMask; | 
|  | bool alphaToCoverage; | 
|  | bool centroid; | 
|  | VkFrontFace frontFace; | 
|  | VkFormat depthFormat; | 
|  | }; | 
|  |  | 
|  | struct State : States | 
|  | { | 
|  | bool operator==(const State &state) const; | 
|  |  | 
|  | int colorWriteActive(int index) const | 
|  | { | 
|  | return (colorWriteMask >> (index * 4)) & 0xF; | 
|  | } | 
|  |  | 
|  | uint32_t hash; | 
|  | }; | 
|  |  | 
|  | struct Stencil | 
|  | { | 
|  | int64_t testMaskQ; | 
|  | int64_t referenceMaskedQ; | 
|  | int64_t referenceMaskedSignedQ; | 
|  | int64_t writeMaskQ; | 
|  | int64_t invWriteMaskQ; | 
|  | int64_t referenceQ; | 
|  |  | 
|  | void set(int reference, int testMask, int writeMask) | 
|  | { | 
|  | referenceQ = replicate(reference); | 
|  | testMaskQ = replicate(testMask); | 
|  | writeMaskQ = replicate(writeMask); | 
|  | invWriteMaskQ = ~writeMaskQ; | 
|  | referenceMaskedQ = referenceQ & testMaskQ; | 
|  | referenceMaskedSignedQ = replicate(((reference & testMask) + 0x80) & 0xFF); | 
|  | } | 
|  |  | 
|  | static int64_t replicate(int b) | 
|  | { | 
|  | int64_t w = b & 0xFF; | 
|  |  | 
|  | return (w << 0) | (w << 8) | (w << 16) | (w << 24) | (w << 32) | (w << 40) | (w << 48) | (w << 56); | 
|  | } | 
|  | }; | 
|  |  | 
|  | struct Factor | 
|  | { | 
|  | word4 alphaReference4; | 
|  |  | 
|  | word4 blendConstant4W[4]; | 
|  | float4 blendConstant4F[4]; | 
|  | word4 invBlendConstant4W[4]; | 
|  | float4 invBlendConstant4F[4]; | 
|  | }; | 
|  |  | 
|  | public: | 
|  | using RoutineType = RasterizerFunction::RoutineType; | 
|  |  | 
|  | PixelProcessor(); | 
|  |  | 
|  | virtual ~PixelProcessor(); | 
|  |  | 
|  | void setBlendConstant(const Color<float> &blendConstant); | 
|  |  | 
|  | protected: | 
|  | const State update(const Context* context) const; | 
|  | RoutineType routine(const State &state, vk::PipelineLayout const *pipelineLayout, | 
|  | SpirvShader const *pixelShader, const vk::DescriptorSet::Bindings &descriptorSets); | 
|  | void setRoutineCacheSize(int routineCacheSize); | 
|  |  | 
|  | // Other semi-constants | 
|  | Factor factor; | 
|  |  | 
|  | private: | 
|  | using RoutineCacheType = RoutineCacheT<State, RasterizerFunction::CFunctionType>; | 
|  | RoutineCacheType *routineCache; | 
|  | }; | 
|  | } | 
|  |  | 
|  | #endif   // sw_PixelProcessor_hpp |