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