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