xref: /aosp_15_r20/external/swiftshader/src/Device/Blitter.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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