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