• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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