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