blob: d9cb93a9856489f4e1719743bacbb83b7c7b134d [file] [log] [blame]
Nicolas Capens68a82382018-10-02 13:16:55 -04001// 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
Ben Claytoneea9d352019-08-29 01:05:14 +010018#include "Memset.hpp"
Nicolas Capens68a82382018-10-02 13:16:55 -040019#include "RoutineCache.hpp"
20#include "Reactor/Reactor.hpp"
Antonio Maiorano42fd1592020-04-27 11:30:40 -040021#include "Vulkan/VkFormat.hpp"
Nicolas Capens68a82382018-10-02 13:16:55 -040022
Ben Clayton377573c2020-04-03 20:36:40 +010023#include "marl/mutex.h"
24#include "marl/tsa.h"
25
Nicolas Capens302a9722019-06-21 12:07:42 -040026#include <cstring>
Nicolas Capens68a82382018-10-02 13:16:55 -040027
Nicolas Capens157ba262019-12-10 17:49:14 -050028namespace vk {
Alexis Hetu33642272019-03-01 11:55:59 -050029
Nicolas Capens157ba262019-12-10 17:49:14 -050030class Image;
31class Buffer;
32
33} // namespace vk
34
35namespace sw {
36
37class Blitter
Nicolas Capens68a82382018-10-02 13:16:55 -040038{
Nicolas Capens157ba262019-12-10 17:49:14 -050039 struct Options
Nicolas Capens68a82382018-10-02 13:16:55 -040040 {
Nicolas Capens157ba262019-12-10 17:49:14 -050041 explicit Options() = default;
42 explicit Options(bool filter, bool allowSRGBConversion)
Ben Claytonfccfc562019-12-17 20:37:31 +000043 : writeMask(0xF)
44 , clearOperation(false)
45 , filter(filter)
46 , allowSRGBConversion(allowSRGBConversion)
47 , clampToEdge(false)
48 {}
Nicolas Capens157ba262019-12-10 17:49:14 -050049 explicit Options(unsigned int writeMask)
Ben Claytonfccfc562019-12-17 20:37:31 +000050 : writeMask(writeMask)
51 , clearOperation(true)
52 , filter(false)
53 , allowSRGBConversion(true)
54 , clampToEdge(false)
55 {}
Nicolas Capens157ba262019-12-10 17:49:14 -050056
57 union
Nicolas Capens68a82382018-10-02 13:16:55 -040058 {
Nicolas Capens157ba262019-12-10 17:49:14 -050059 struct
Nicolas Capens68a82382018-10-02 13:16:55 -040060 {
Nicolas Capens157ba262019-12-10 17:49:14 -050061 bool writeRed : 1;
62 bool writeGreen : 1;
63 bool writeBlue : 1;
64 bool writeAlpha : 1;
Nicolas Capens68a82382018-10-02 13:16:55 -040065 };
66
Nicolas Capens157ba262019-12-10 17:49:14 -050067 unsigned char writeMask;
Nicolas Capens68a82382018-10-02 13:16:55 -040068 };
69
Nicolas Capens157ba262019-12-10 17:49:14 -050070 bool clearOperation : 1;
71 bool filter : 1;
72 bool allowSRGBConversion : 1;
73 bool clampToEdge : 1;
Nicolas Capens68a82382018-10-02 13:16:55 -040074 };
Nicolas Capens157ba262019-12-10 17:49:14 -050075
76 struct State : Memset<State>, Options
77 {
Ben Claytonfccfc562019-12-17 20:37:31 +000078 State()
79 : Memset(this, 0)
80 {}
81 State(const Options &options)
82 : Memset(this, 0)
83 , Options(options)
84 {}
85 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 {}
Nicolas Capens157ba262019-12-10 17:49:14 -050093
Nicolas Capens157ba262019-12-10 17:49:14 -050094 vk::Format sourceFormat;
95 vk::Format destFormat;
96 int srcSamples = 0;
97 int destSamples = 0;
Alexis Hetu18daa812020-03-11 17:06:53 -040098 bool filter3D = false;
Nicolas Capens157ba262019-12-10 17:49:14 -050099 };
Ben Claytonac43aa72020-04-04 00:48:13 +0100100 friend std::hash<Blitter::State>;
Nicolas Capens157ba262019-12-10 17:49:14 -0500101
102 struct BlitData
103 {
104 void *source;
105 void *dest;
106 int sPitchB;
107 int dPitchB;
108 int sSliceB;
109 int dSliceB;
110
111 float x0;
112 float y0;
Alexis Hetu18daa812020-03-11 17:06:53 -0400113 float z0;
Nicolas Capens157ba262019-12-10 17:49:14 -0500114 float w;
115 float h;
Alexis Hetu18daa812020-03-11 17:06:53 -0400116 float d;
Nicolas Capens157ba262019-12-10 17:49:14 -0500117
Nicolas Capens157ba262019-12-10 17:49:14 -0500118 int x0d;
119 int x1d;
Alexis Hetu18daa812020-03-11 17:06:53 -0400120 int y0d;
121 int y1d;
122 int z0d;
123 int z1d;
Nicolas Capens157ba262019-12-10 17:49:14 -0500124
125 int sWidth;
126 int sHeight;
Alexis Hetu18daa812020-03-11 17:06:53 -0400127 int sDepth;
128
129 bool filter3D;
Nicolas Capens157ba262019-12-10 17:49:14 -0500130 };
131
132 struct CubeBorderData
133 {
134 void *layers;
135 int pitchB;
136 uint32_t layerSize;
137 uint32_t dim;
138 };
139
140public:
141 Blitter();
142 virtual ~Blitter();
143
Nicolas Capensb3240d02020-06-10 22:40:19 -0400144 void clear(void *clearValue, vk::Format clearFormat, vk::Image *dest, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea = nullptr);
Nicolas Capens157ba262019-12-10 17:49:14 -0500145
146 void blit(const vk::Image *src, vk::Image *dst, VkImageBlit region, VkFilter filter);
Nicolas Capens32f4be12020-06-10 13:14:07 -0400147 void copy(const vk::Image *src, uint8_t *dst, unsigned int dstPitch);
Nicolas Capens157ba262019-12-10 17:49:14 -0500148
Alexis Hetu46159712020-06-15 16:13:51 -0400149 void updateBorders(vk::Image *image, const VkImageSubresource &subresource);
Nicolas Capens157ba262019-12-10 17:49:14 -0500150
151private:
Ben Claytonfccfc562019-12-17 20:37:31 +0000152 enum Edge
153 {
154 TOP,
155 BOTTOM,
156 RIGHT,
157 LEFT
158 };
Nicolas Capens157ba262019-12-10 17:49:14 -0500159
Nicolas Capensb3240d02020-06-10 22:40:19 -0400160 bool fastClear(void *clearValue, vk::Format clearFormat, vk::Image *dest, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea);
Nicolas Capens157ba262019-12-10 17:49:14 -0500161
162 Float4 readFloat4(Pointer<Byte> element, const State &state);
163 void write(Float4 &color, Pointer<Byte> element, const State &state);
164 Int4 readInt4(Pointer<Byte> element, const State &state);
165 void write(Int4 &color, Pointer<Byte> element, const State &state);
166 static void ApplyScaleAndClamp(Float4 &value, const State &state, bool preScaled = false);
167 static Int ComputeOffset(Int &x, Int &y, Int &pitchB, int bytes);
Alexis Hetu18daa812020-03-11 17:06:53 -0400168 static Int ComputeOffset(Int &x, Int &y, Int &z, Int &sliceB, Int &pitchB, int bytes);
Nicolas Capens2883de92020-01-27 14:58:14 -0500169 static Float4 LinearToSRGB(const Float4 &color);
170 static Float4 sRGBtoLinear(const Float4 &color);
Nicolas Capens157ba262019-12-10 17:49:14 -0500171
Ben Claytonfccfc562019-12-17 20:37:31 +0000172 using BlitFunction = FunctionT<void(const BlitData *)>;
Nicolas Capens157ba262019-12-10 17:49:14 -0500173 using BlitRoutineType = BlitFunction::RoutineType;
174 BlitRoutineType getBlitRoutine(const State &state);
175 BlitRoutineType generate(const State &state);
Alexis Hetu18daa812020-03-11 17:06:53 -0400176 Float4 sample(Pointer<Byte> &source, Float &x, Float &y, Float &z,
177 Int &sWidth, Int &sHeight, Int &sDepth,
178 Int &sSliceB, Int &sPitchB, const State &state);
Nicolas Capens157ba262019-12-10 17:49:14 -0500179
Ben Claytonfccfc562019-12-17 20:37:31 +0000180 using CornerUpdateFunction = FunctionT<void(const CubeBorderData *)>;
Nicolas Capens157ba262019-12-10 17:49:14 -0500181 using CornerUpdateRoutineType = CornerUpdateFunction::RoutineType;
182 CornerUpdateRoutineType getCornerUpdateRoutine(const State &state);
Ben Claytonfccfc562019-12-17 20:37:31 +0000183 CornerUpdateRoutineType generateCornerUpdate(const State &state);
184 void computeCubeCorner(Pointer<Byte> &layer, Int &x0, Int &x1, Int &y0, Int &y1, Int &pitchB, const State &state);
Nicolas Capens157ba262019-12-10 17:49:14 -0500185
Ben Claytonfccfc562019-12-17 20:37:31 +0000186 void copyCubeEdge(vk::Image *image,
Alexis Hetu46159712020-06-15 16:13:51 -0400187 const VkImageSubresource &dstSubresource, Edge dstEdge,
188 const VkImageSubresource &srcSubresource, Edge srcEdge);
Nicolas Capens157ba262019-12-10 17:49:14 -0500189
Ben Clayton377573c2020-04-03 20:36:40 +0100190 marl::mutex blitMutex;
191 RoutineCache<State, BlitFunction::CFunctionType> blitCache GUARDED_BY(blitMutex);
192
193 marl::mutex cornerUpdateMutex;
194 RoutineCache<State, CornerUpdateFunction::CFunctionType> cornerUpdateCache GUARDED_BY(cornerUpdateMutex);
Nicolas Capens157ba262019-12-10 17:49:14 -0500195};
196
197} // namespace sw
Nicolas Capens68a82382018-10-02 13:16:55 -0400198
Ben Claytonac43aa72020-04-04 00:48:13 +0100199namespace std {
200
201template<>
202struct hash<sw::Blitter::State>
203{
204 uint64_t operator()(const sw::Blitter::State &state) const
205 {
206 uint64_t hash = state.sourceFormat;
207 hash = hash * 31 + state.destFormat;
208 hash = hash * 31 + state.srcSamples;
209 hash = hash * 31 + state.destSamples;
210 hash = hash * 31 + state.filter3D;
211 return hash;
212 }
213};
214
215} // namespace std
216
Ben Claytonfccfc562019-12-17 20:37:31 +0000217#endif // sw_Blitter_hpp