1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*03ce13f7SAndroid Build Coastguard Worker // 7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*03ce13f7SAndroid Build Coastguard Worker // 9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License. 14*03ce13f7SAndroid Build Coastguard Worker 15*03ce13f7SAndroid Build Coastguard Worker #ifndef sw_Blitter_hpp 16*03ce13f7SAndroid Build Coastguard Worker #define sw_Blitter_hpp 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "Memset.hpp" 19*03ce13f7SAndroid Build Coastguard Worker #include "RoutineCache.hpp" 20*03ce13f7SAndroid Build Coastguard Worker #include "Reactor/Reactor.hpp" 21*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkFormat.hpp" 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker #include "marl/mutex.h" 24*03ce13f7SAndroid Build Coastguard Worker #include "marl/tsa.h" 25*03ce13f7SAndroid Build Coastguard Worker 26*03ce13f7SAndroid Build Coastguard Worker #include <cstring> 27*03ce13f7SAndroid Build Coastguard Worker 28*03ce13f7SAndroid Build Coastguard Worker namespace vk { 29*03ce13f7SAndroid Build Coastguard Worker 30*03ce13f7SAndroid Build Coastguard Worker class Image; 31*03ce13f7SAndroid Build Coastguard Worker class ImageView; 32*03ce13f7SAndroid Build Coastguard Worker 33*03ce13f7SAndroid Build Coastguard Worker } // namespace vk 34*03ce13f7SAndroid Build Coastguard Worker 35*03ce13f7SAndroid Build Coastguard Worker namespace sw { 36*03ce13f7SAndroid Build Coastguard Worker 37*03ce13f7SAndroid Build Coastguard Worker class Blitter 38*03ce13f7SAndroid Build Coastguard Worker { 39*03ce13f7SAndroid Build Coastguard Worker struct Options 40*03ce13f7SAndroid Build Coastguard Worker { 41*03ce13f7SAndroid Build Coastguard Worker explicit Options() = default; Optionssw::Blitter::Options42*03ce13f7SAndroid Build Coastguard Worker explicit Options(bool filter, bool allowSRGBConversion) 43*03ce13f7SAndroid Build Coastguard Worker : writeMask(0xF) 44*03ce13f7SAndroid Build Coastguard Worker , clearOperation(false) 45*03ce13f7SAndroid Build Coastguard Worker , filter(filter) 46*03ce13f7SAndroid Build Coastguard Worker , allowSRGBConversion(allowSRGBConversion) 47*03ce13f7SAndroid Build Coastguard Worker , clampToEdge(false) 48*03ce13f7SAndroid Build Coastguard Worker {} Optionssw::Blitter::Options49*03ce13f7SAndroid Build Coastguard Worker explicit Options(unsigned int writeMask) 50*03ce13f7SAndroid Build Coastguard Worker : writeMask(writeMask) 51*03ce13f7SAndroid Build Coastguard Worker , clearOperation(true) 52*03ce13f7SAndroid Build Coastguard Worker , filter(false) 53*03ce13f7SAndroid Build Coastguard Worker , allowSRGBConversion(true) 54*03ce13f7SAndroid Build Coastguard Worker , clampToEdge(false) 55*03ce13f7SAndroid Build Coastguard Worker {} 56*03ce13f7SAndroid Build Coastguard Worker 57*03ce13f7SAndroid Build Coastguard Worker union 58*03ce13f7SAndroid Build Coastguard Worker { 59*03ce13f7SAndroid Build Coastguard Worker struct 60*03ce13f7SAndroid Build Coastguard Worker { 61*03ce13f7SAndroid Build Coastguard Worker bool writeRed : 1; 62*03ce13f7SAndroid Build Coastguard Worker bool writeGreen : 1; 63*03ce13f7SAndroid Build Coastguard Worker bool writeBlue : 1; 64*03ce13f7SAndroid Build Coastguard Worker bool writeAlpha : 1; 65*03ce13f7SAndroid Build Coastguard Worker }; 66*03ce13f7SAndroid Build Coastguard Worker 67*03ce13f7SAndroid Build Coastguard Worker unsigned char writeMask; 68*03ce13f7SAndroid Build Coastguard Worker }; 69*03ce13f7SAndroid Build Coastguard Worker 70*03ce13f7SAndroid Build Coastguard Worker bool clearOperation : 1; 71*03ce13f7SAndroid Build Coastguard Worker bool filter : 1; 72*03ce13f7SAndroid Build Coastguard Worker bool allowSRGBConversion : 1; 73*03ce13f7SAndroid Build Coastguard Worker bool clampToEdge : 1; 74*03ce13f7SAndroid Build Coastguard Worker }; 75*03ce13f7SAndroid Build Coastguard Worker 76*03ce13f7SAndroid Build Coastguard Worker struct State : Memset<State>, Options 77*03ce13f7SAndroid Build Coastguard Worker { Statesw::Blitter::State78*03ce13f7SAndroid Build Coastguard Worker State() 79*03ce13f7SAndroid Build Coastguard Worker : Memset(this, 0) 80*03ce13f7SAndroid Build Coastguard Worker {} Statesw::Blitter::State81*03ce13f7SAndroid Build Coastguard Worker State(const Options &options) 82*03ce13f7SAndroid Build Coastguard Worker : Memset(this, 0) 83*03ce13f7SAndroid Build Coastguard Worker , Options(options) 84*03ce13f7SAndroid Build Coastguard Worker {} Statesw::Blitter::State85*03ce13f7SAndroid Build Coastguard Worker State(vk::Format sourceFormat, vk::Format destFormat, int srcSamples, int destSamples, const Options &options) 86*03ce13f7SAndroid Build Coastguard Worker : Memset(this, 0) 87*03ce13f7SAndroid Build Coastguard Worker , Options(options) 88*03ce13f7SAndroid Build Coastguard Worker , sourceFormat(sourceFormat) 89*03ce13f7SAndroid Build Coastguard Worker , destFormat(destFormat) 90*03ce13f7SAndroid Build Coastguard Worker , srcSamples(srcSamples) 91*03ce13f7SAndroid Build Coastguard Worker , destSamples(destSamples) 92*03ce13f7SAndroid Build Coastguard Worker {} 93*03ce13f7SAndroid Build Coastguard Worker 94*03ce13f7SAndroid Build Coastguard Worker vk::Format sourceFormat; 95*03ce13f7SAndroid Build Coastguard Worker vk::Format destFormat; 96*03ce13f7SAndroid Build Coastguard Worker int srcSamples = 0; 97*03ce13f7SAndroid Build Coastguard Worker int destSamples = 0; 98*03ce13f7SAndroid Build Coastguard Worker bool filter3D = false; 99*03ce13f7SAndroid Build Coastguard Worker }; 100*03ce13f7SAndroid Build Coastguard Worker friend std::hash<Blitter::State>; 101*03ce13f7SAndroid Build Coastguard Worker 102*03ce13f7SAndroid Build Coastguard Worker struct BlitData 103*03ce13f7SAndroid Build Coastguard Worker { 104*03ce13f7SAndroid Build Coastguard Worker const void *source; 105*03ce13f7SAndroid Build Coastguard Worker void *dest; 106*03ce13f7SAndroid Build Coastguard Worker uint32_t sPitchB; 107*03ce13f7SAndroid Build Coastguard Worker uint32_t dPitchB; 108*03ce13f7SAndroid Build Coastguard Worker uint32_t sSliceB; 109*03ce13f7SAndroid Build Coastguard Worker uint32_t dSliceB; 110*03ce13f7SAndroid Build Coastguard Worker 111*03ce13f7SAndroid Build Coastguard Worker float x0; 112*03ce13f7SAndroid Build Coastguard Worker float y0; 113*03ce13f7SAndroid Build Coastguard Worker float z0; 114*03ce13f7SAndroid Build Coastguard Worker float w; 115*03ce13f7SAndroid Build Coastguard Worker float h; 116*03ce13f7SAndroid Build Coastguard Worker float d; 117*03ce13f7SAndroid Build Coastguard Worker 118*03ce13f7SAndroid Build Coastguard Worker int x0d; 119*03ce13f7SAndroid Build Coastguard Worker int x1d; 120*03ce13f7SAndroid Build Coastguard Worker int y0d; 121*03ce13f7SAndroid Build Coastguard Worker int y1d; 122*03ce13f7SAndroid Build Coastguard Worker int z0d; 123*03ce13f7SAndroid Build Coastguard Worker int z1d; 124*03ce13f7SAndroid Build Coastguard Worker 125*03ce13f7SAndroid Build Coastguard Worker int sWidth; 126*03ce13f7SAndroid Build Coastguard Worker int sHeight; 127*03ce13f7SAndroid Build Coastguard Worker int sDepth; 128*03ce13f7SAndroid Build Coastguard Worker 129*03ce13f7SAndroid Build Coastguard Worker bool filter3D; 130*03ce13f7SAndroid Build Coastguard Worker }; 131*03ce13f7SAndroid Build Coastguard Worker 132*03ce13f7SAndroid Build Coastguard Worker struct CubeBorderData 133*03ce13f7SAndroid Build Coastguard Worker { 134*03ce13f7SAndroid Build Coastguard Worker void *layers; 135*03ce13f7SAndroid Build Coastguard Worker uint32_t pitchB; 136*03ce13f7SAndroid Build Coastguard Worker uint32_t layerSize; 137*03ce13f7SAndroid Build Coastguard Worker uint32_t dim; 138*03ce13f7SAndroid Build Coastguard Worker }; 139*03ce13f7SAndroid Build Coastguard Worker 140*03ce13f7SAndroid Build Coastguard Worker public: 141*03ce13f7SAndroid Build Coastguard Worker Blitter(); 142*03ce13f7SAndroid Build Coastguard Worker virtual ~Blitter(); 143*03ce13f7SAndroid Build Coastguard Worker 144*03ce13f7SAndroid Build Coastguard Worker void clear(const void *clearValue, vk::Format clearFormat, vk::Image *dest, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea = nullptr); 145*03ce13f7SAndroid Build Coastguard Worker 146*03ce13f7SAndroid Build Coastguard Worker void blit(const vk::Image *src, vk::Image *dst, VkImageBlit2KHR region, VkFilter filter); 147*03ce13f7SAndroid Build Coastguard Worker void resolve(const vk::Image *src, vk::Image *dst, VkImageResolve2KHR region); 148*03ce13f7SAndroid Build Coastguard Worker void resolveDepthStencil(const vk::ImageView *src, vk::ImageView *dst, VkResolveModeFlagBits depthResolveMode, VkResolveModeFlagBits stencilResolveMode); 149*03ce13f7SAndroid Build Coastguard Worker void copy(const vk::Image *src, uint8_t *dst, unsigned int dstPitch); 150*03ce13f7SAndroid Build Coastguard Worker 151*03ce13f7SAndroid Build Coastguard Worker void updateBorders(const vk::Image *image, const VkImageSubresource &subresource); 152*03ce13f7SAndroid Build Coastguard Worker 153*03ce13f7SAndroid Build Coastguard Worker private: 154*03ce13f7SAndroid Build Coastguard Worker enum Edge 155*03ce13f7SAndroid Build Coastguard Worker { 156*03ce13f7SAndroid Build Coastguard Worker TOP, 157*03ce13f7SAndroid Build Coastguard Worker BOTTOM, 158*03ce13f7SAndroid Build Coastguard Worker RIGHT, 159*03ce13f7SAndroid Build Coastguard Worker LEFT 160*03ce13f7SAndroid Build Coastguard Worker }; 161*03ce13f7SAndroid Build Coastguard Worker 162*03ce13f7SAndroid Build Coastguard Worker bool fastClear(const void *clearValue, vk::Format clearFormat, vk::Image *dest, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea); 163*03ce13f7SAndroid Build Coastguard Worker bool fastResolve(const vk::Image *src, vk::Image *dst, VkImageResolve2KHR region); 164*03ce13f7SAndroid Build Coastguard Worker 165*03ce13f7SAndroid Build Coastguard Worker Float4 readFloat4(Pointer<Byte> element, const State &state); 166*03ce13f7SAndroid Build Coastguard Worker void write(Float4 &color, Pointer<Byte> element, const State &state); 167*03ce13f7SAndroid Build Coastguard Worker Int4 readInt4(Pointer<Byte> element, const State &state); 168*03ce13f7SAndroid Build Coastguard Worker void write(Int4 &color, Pointer<Byte> element, const State &state); 169*03ce13f7SAndroid Build Coastguard Worker static void ApplyScaleAndClamp(Float4 &value, const State &state, bool preScaled = false); 170*03ce13f7SAndroid Build Coastguard Worker static Int ComputeOffset(Int &x, Int &y, Int &pitchB, int bytes); 171*03ce13f7SAndroid Build Coastguard Worker static Int ComputeOffset(Int &x, Int &y, Int &z, Int &sliceB, Int &pitchB, int bytes); 172*03ce13f7SAndroid Build Coastguard Worker 173*03ce13f7SAndroid Build Coastguard Worker using BlitFunction = FunctionT<void(const BlitData *)>; 174*03ce13f7SAndroid Build Coastguard Worker using BlitRoutineType = BlitFunction::RoutineType; 175*03ce13f7SAndroid Build Coastguard Worker BlitRoutineType getBlitRoutine(const State &state); 176*03ce13f7SAndroid Build Coastguard Worker BlitRoutineType generate(const State &state); 177*03ce13f7SAndroid Build Coastguard Worker Float4 sample(Pointer<Byte> &source, Float &x, Float &y, Float &z, 178*03ce13f7SAndroid Build Coastguard Worker Int &sWidth, Int &sHeight, Int &sDepth, 179*03ce13f7SAndroid Build Coastguard Worker Int &sSliceB, Int &sPitchB, const State &state); 180*03ce13f7SAndroid Build Coastguard Worker 181*03ce13f7SAndroid Build Coastguard Worker using CornerUpdateFunction = FunctionT<void(const CubeBorderData *)>; 182*03ce13f7SAndroid Build Coastguard Worker using CornerUpdateRoutineType = CornerUpdateFunction::RoutineType; 183*03ce13f7SAndroid Build Coastguard Worker CornerUpdateRoutineType getCornerUpdateRoutine(const State &state); 184*03ce13f7SAndroid Build Coastguard Worker CornerUpdateRoutineType generateCornerUpdate(const State &state); 185*03ce13f7SAndroid Build Coastguard Worker void computeCubeCorner(Pointer<Byte> &layer, Int &x0, Int &x1, Int &y0, Int &y1, Int &pitchB, const State &state); 186*03ce13f7SAndroid Build Coastguard Worker 187*03ce13f7SAndroid Build Coastguard Worker void copyCubeEdge(const vk::Image *image, 188*03ce13f7SAndroid Build Coastguard Worker const VkImageSubresource &dstSubresource, Edge dstEdge, 189*03ce13f7SAndroid Build Coastguard Worker const VkImageSubresource &srcSubresource, Edge srcEdge); 190*03ce13f7SAndroid Build Coastguard Worker 191*03ce13f7SAndroid Build Coastguard Worker marl::mutex blitMutex; 192*03ce13f7SAndroid Build Coastguard Worker RoutineCache<State, BlitFunction::CFunctionType> blitCache GUARDED_BY(blitMutex); 193*03ce13f7SAndroid Build Coastguard Worker 194*03ce13f7SAndroid Build Coastguard Worker marl::mutex cornerUpdateMutex; 195*03ce13f7SAndroid Build Coastguard Worker RoutineCache<State, CornerUpdateFunction::CFunctionType> cornerUpdateCache GUARDED_BY(cornerUpdateMutex); 196*03ce13f7SAndroid Build Coastguard Worker }; 197*03ce13f7SAndroid Build Coastguard Worker 198*03ce13f7SAndroid Build Coastguard Worker } // namespace sw 199*03ce13f7SAndroid Build Coastguard Worker 200*03ce13f7SAndroid Build Coastguard Worker namespace std { 201*03ce13f7SAndroid Build Coastguard Worker 202*03ce13f7SAndroid Build Coastguard Worker template<> 203*03ce13f7SAndroid Build Coastguard Worker struct hash<sw::Blitter::State> 204*03ce13f7SAndroid Build Coastguard Worker { operator ()std::hash205*03ce13f7SAndroid Build Coastguard Worker uint64_t operator()(const sw::Blitter::State &state) const 206*03ce13f7SAndroid Build Coastguard Worker { 207*03ce13f7SAndroid Build Coastguard Worker uint64_t hash = state.sourceFormat; 208*03ce13f7SAndroid Build Coastguard Worker hash = hash * 31 + state.destFormat; 209*03ce13f7SAndroid Build Coastguard Worker hash = hash * 31 + state.srcSamples; 210*03ce13f7SAndroid Build Coastguard Worker hash = hash * 31 + state.destSamples; 211*03ce13f7SAndroid Build Coastguard Worker hash = hash * 31 + state.filter3D; 212*03ce13f7SAndroid Build Coastguard Worker return hash; 213*03ce13f7SAndroid Build Coastguard Worker } 214*03ce13f7SAndroid Build Coastguard Worker }; 215*03ce13f7SAndroid Build Coastguard Worker 216*03ce13f7SAndroid Build Coastguard Worker } // namespace std 217*03ce13f7SAndroid Build Coastguard Worker 218*03ce13f7SAndroid Build Coastguard Worker #endif // sw_Blitter_hpp 219