blob: 7bcdb7e3087d8b87d0839dab3a9365d573ed9e46 [file] [log] [blame]
Jamie Madilld2b50a02016-06-09 00:13:35 -07001//
2// Copyright 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// renderer_utils:
7// Helper methods pertaining to most or all back-ends.
8//
9
10#ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_
11#define LIBANGLE_RENDERER_RENDERER_UTILS_H_
12
13#include <cstdint>
14
Jamie Madilldcc9b512017-06-05 15:28:45 -040015#include <limits>
Jamie Madilld2b50a02016-06-09 00:13:35 -070016#include <map>
17
Jamie Madillfb05bcb2017-06-07 15:43:18 -040018#include "common/angleutils.h"
Jamie Madilld2b50a02016-06-09 00:13:35 -070019#include "libANGLE/angletypes.h"
20
Jamie Madill86e0b7f2016-08-09 11:10:29 -040021namespace angle
22{
23struct Format;
Jamie Madilldb9c69e2018-07-18 17:23:47 -040024enum class FormatID;
Jamie Madill222c5172017-07-19 16:15:42 -040025} // namespace angle
Jamie Madill86e0b7f2016-08-09 11:10:29 -040026
Jamie Madilld2b50a02016-06-09 00:13:35 -070027namespace gl
28{
29struct FormatType;
30struct InternalFormat;
Jamie Madill222c5172017-07-19 16:15:42 -040031} // namespace gl
32
33namespace egl
34{
35class AttributeMap;
36} // namespace egl
Jamie Madilld2b50a02016-06-09 00:13:35 -070037
38namespace rx
39{
Jamie Madillc1fd7372018-10-26 22:48:39 -040040class ContextImpl;
Jamie Madilld2b50a02016-06-09 00:13:35 -070041
Jamie Madilldcc9b512017-06-05 15:28:45 -040042class ResourceSerial
43{
44 public:
45 constexpr ResourceSerial() : mValue(kDirty) {}
Jamie Madill9959f542017-09-12 15:22:56 -040046 explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {}
Jamie Madilldcc9b512017-06-05 15:28:45 -040047 constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; }
48 constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; }
49
50 void dirty() { mValue = kDirty; }
Jamie Madill9959f542017-09-12 15:22:56 -040051 void clear() { mValue = kEmpty; }
52
53 constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; }
54 constexpr bool empty() const { return mValue == kEmpty; }
Jamie Madilldcc9b512017-06-05 15:28:45 -040055
56 private:
57 constexpr static uintptr_t kDirty = std::numeric_limits<uintptr_t>::max();
Jamie Madill9959f542017-09-12 15:22:56 -040058 constexpr static uintptr_t kEmpty = 0;
Jamie Madilldcc9b512017-06-05 15:28:45 -040059
60 uintptr_t mValue;
61};
62
Jamie Madillfb05bcb2017-06-07 15:43:18 -040063class SerialFactory;
64
65class Serial final
66{
67 public:
Jamie Madill0e7f1732017-09-09 23:32:50 -040068 constexpr Serial() : mValue(kInvalid) {}
Jamie Madillfb05bcb2017-06-07 15:43:18 -040069 constexpr Serial(const Serial &other) = default;
70 Serial &operator=(const Serial &other) = default;
71
Jamie Madill0e7f1732017-09-09 23:32:50 -040072 constexpr bool operator==(const Serial &other) const
73 {
74 return mValue != kInvalid && mValue == other.mValue;
75 }
Jamie Madillf2f6d372018-01-10 21:37:23 -050076 constexpr bool operator==(uint32_t value) const
77 {
78 return mValue != kInvalid && mValue == static_cast<uint64_t>(value);
79 }
Jamie Madill0e7f1732017-09-09 23:32:50 -040080 constexpr bool operator!=(const Serial &other) const
81 {
82 return mValue == kInvalid || mValue != other.mValue;
83 }
Jamie Madillfb05bcb2017-06-07 15:43:18 -040084 constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; }
85 constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; }
86 constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; }
87 constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; }
88
Jamie Madillf2f6d372018-01-10 21:37:23 -050089 constexpr bool operator<(uint32_t value) const { return mValue < static_cast<uint64_t>(value); }
90
91 // Useful for serialization.
92 constexpr uint64_t getValue() const { return mValue; }
93
Jamie Madillfb05bcb2017-06-07 15:43:18 -040094 private:
95 friend class SerialFactory;
96 constexpr explicit Serial(uint64_t value) : mValue(value) {}
97 uint64_t mValue;
Jamie Madill0e7f1732017-09-09 23:32:50 -040098 static constexpr uint64_t kInvalid = 0;
Jamie Madillfb05bcb2017-06-07 15:43:18 -040099};
100
101class SerialFactory final : angle::NonCopyable
102{
103 public:
104 SerialFactory() : mSerial(1) {}
105
106 Serial generate()
107 {
108 ASSERT(mSerial != std::numeric_limits<uint64_t>::max());
109 return Serial(mSerial++);
110 }
111
112 private:
113 uint64_t mSerial;
114};
115
Jamie Madilla5b15612016-08-09 11:10:27 -0400116using MipGenerationFunction = void (*)(size_t sourceWidth,
117 size_t sourceHeight,
118 size_t sourceDepth,
119 const uint8_t *sourceData,
120 size_t sourceRowPitch,
121 size_t sourceDepthPitch,
122 uint8_t *destData,
123 size_t destRowPitch,
124 size_t destDepthPitch);
125
Jamie Madill522095f2018-07-23 14:59:41 -0400126typedef void (*PixelReadFunction)(const uint8_t *source, uint8_t *dest);
127typedef void (*PixelWriteFunction)(const uint8_t *source, uint8_t *dest);
128typedef void (*PixelCopyFunction)(const uint8_t *source, uint8_t *dest);
Jamie Madilld2b50a02016-06-09 00:13:35 -0700129
Jamie Madill4f57e5f2016-10-27 17:36:53 -0400130class FastCopyFunctionMap
131{
132 public:
133 struct Entry
134 {
Jamie Madilldb9c69e2018-07-18 17:23:47 -0400135 angle::FormatID formatID;
Jamie Madill522095f2018-07-23 14:59:41 -0400136 PixelCopyFunction func;
Jamie Madill4f57e5f2016-10-27 17:36:53 -0400137 };
138
139 constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {}
140
141 constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {}
142
Jamie Madilldb9c69e2018-07-18 17:23:47 -0400143 bool has(angle::FormatID formatID) const;
Jamie Madill522095f2018-07-23 14:59:41 -0400144 PixelCopyFunction get(angle::FormatID formatID) const;
Jamie Madill4f57e5f2016-10-27 17:36:53 -0400145
146 private:
147 size_t mSize;
148 const Entry *mData;
149};
Jamie Madilld2b50a02016-06-09 00:13:35 -0700150
Corentin Wallezcda6af12017-10-30 19:20:37 -0400151struct PackPixelsParams
Jamie Madilld2b50a02016-06-09 00:13:35 -0700152{
153 PackPixelsParams();
154 PackPixelsParams(const gl::Rectangle &area,
Jamie Madilldb9c69e2018-07-18 17:23:47 -0400155 const angle::Format &destFormat,
Jamie Madilld2b50a02016-06-09 00:13:35 -0700156 GLuint outputPitch,
Frank Henigman1ffad842018-09-24 23:40:45 -0400157 bool reverseRowOrderIn,
Corentin Wallezcda6af12017-10-30 19:20:37 -0400158 gl::Buffer *packBufferIn,
Jamie Madilld2b50a02016-06-09 00:13:35 -0700159 ptrdiff_t offset);
160
161 gl::Rectangle area;
Jamie Madilldb9c69e2018-07-18 17:23:47 -0400162 const angle::Format *destFormat;
Jamie Madilld2b50a02016-06-09 00:13:35 -0700163 GLuint outputPitch;
164 gl::Buffer *packBuffer;
Frank Henigman1ffad842018-09-24 23:40:45 -0400165 bool reverseRowOrder;
Jamie Madilld2b50a02016-06-09 00:13:35 -0700166 ptrdiff_t offset;
167};
168
169void PackPixels(const PackPixelsParams &params,
Jamie Madill86e0b7f2016-08-09 11:10:29 -0400170 const angle::Format &sourceFormat,
Jamie Madilld2b50a02016-06-09 00:13:35 -0700171 int inputPitch,
172 const uint8_t *source,
173 uint8_t *destination);
174
Jamie Madillabaab232017-01-10 12:37:37 -0500175using InitializeTextureDataFunction = void (*)(size_t width,
176 size_t height,
177 size_t depth,
178 uint8_t *output,
179 size_t outputRowPitch,
180 size_t outputDepthPitch);
181
Jamie Madillb2e48632016-08-09 18:08:03 -0400182using LoadImageFunction = void (*)(size_t width,
183 size_t height,
184 size_t depth,
185 const uint8_t *input,
186 size_t inputRowPitch,
187 size_t inputDepthPitch,
188 uint8_t *output,
189 size_t outputRowPitch,
190 size_t outputDepthPitch);
191
192struct LoadImageFunctionInfo
193{
194 LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {}
195 LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion)
196 : loadFunction(loadFunction), requiresConversion(requiresConversion)
197 {
198 }
199
200 LoadImageFunction loadFunction;
201 bool requiresConversion;
202};
203
204using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum);
205
Jamie Madill222c5172017-07-19 16:15:42 -0400206bool ShouldUseDebugLayers(const egl::AttributeMap &attribs);
Geoff Lang24ddc7a2018-06-11 14:56:34 -0400207bool ShouldUseVirtualizedContexts(const egl::AttributeMap &attribs, bool defaultValue);
Jamie Madill222c5172017-07-19 16:15:42 -0400208
Geoff Langd93cd6c2017-08-11 16:32:41 -0400209void CopyImageCHROMIUM(const uint8_t *sourceData,
210 size_t sourceRowPitch,
211 size_t sourcePixelBytes,
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700212 size_t sourceDepthPitch,
Jamie Madill522095f2018-07-23 14:59:41 -0400213 PixelReadFunction pixelReadFunction,
Geoff Langd93cd6c2017-08-11 16:32:41 -0400214 uint8_t *destData,
215 size_t destRowPitch,
216 size_t destPixelBytes,
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700217 size_t destDepthPitch,
Jamie Madill522095f2018-07-23 14:59:41 -0400218 PixelWriteFunction pixelWriteFunction,
Geoff Langd93cd6c2017-08-11 16:32:41 -0400219 GLenum destUnsizedFormat,
220 GLenum destComponentType,
221 size_t width,
222 size_t height,
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700223 size_t depth,
Geoff Langd93cd6c2017-08-11 16:32:41 -0400224 bool unpackFlipY,
225 bool unpackPremultiplyAlpha,
226 bool unpackUnmultiplyAlpha);
227
Jamie Madill42975642017-10-12 12:31:51 -0400228// Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete.
229// This helper class encapsulates handling incomplete textures. Because the GL back-end
230// can take advantage of the driver's incomplete textures, and because clearing multisample
231// textures is so difficult, we can keep an instance of this class in the back-end instead
232// of moving the logic to the Context front-end.
233
234// This interface allows us to call-back to init a multisample texture.
235class MultisampleTextureInitializer
236{
237 public:
Jamie Madill5ad26402017-10-17 15:32:06 -0400238 virtual ~MultisampleTextureInitializer() {}
Jamie Madill666818e2018-11-14 09:54:33 -0500239 virtual angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
240 gl::Texture *glTexture) = 0;
Jamie Madill42975642017-10-12 12:31:51 -0400241};
242
243class IncompleteTextureSet final : angle::NonCopyable
244{
245 public:
246 IncompleteTextureSet();
247 ~IncompleteTextureSet();
248
249 void onDestroy(const gl::Context *context);
250
Jamie Madill666818e2018-11-14 09:54:33 -0500251 angle::Result getIncompleteTexture(const gl::Context *context,
252 gl::TextureType type,
253 MultisampleTextureInitializer *multisampleInitializer,
254 gl::Texture **textureOut);
Jamie Madill42975642017-10-12 12:31:51 -0400255
256 private:
Corentin Wallez99d492c2018-02-27 15:17:10 -0500257 gl::TextureMap mIncompleteTextures;
Jamie Madill42975642017-10-12 12:31:51 -0400258};
259
Luc Ferron46bcea52018-05-31 09:48:36 -0400260// The return value indicate if the data was updated or not.
261template <int cols, int rows>
262bool SetFloatUniformMatrix(unsigned int arrayElementOffset,
263 unsigned int elementCount,
264 GLsizei countIn,
265 GLboolean transpose,
266 const GLfloat *value,
267 uint8_t *targetData);
268
Luc Ferron48cdc2e2018-05-31 09:58:34 -0400269// Helper method to de-tranpose a matrix uniform for an API query.
270void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose);
271
272template <typename NonFloatT>
273void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose);
274
Jamie Madilldb9c69e2018-07-18 17:23:47 -0400275const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type);
Jamie Madillc1fd7372018-10-26 22:48:39 -0400276
277angle::Result ComputeStartVertex(ContextImpl *contextImpl,
278 const gl::IndexRange &indexRange,
279 GLint baseVertex,
280 GLint *firstVertexOut);
281
282angle::Result GetVertexRangeInfo(const gl::Context *context,
283 GLint firstVertex,
284 GLsizei vertexOrIndexCount,
285 GLenum indexTypeOrNone,
286 const void *indices,
287 GLint baseVertex,
288 GLint *startVertexOut,
289 size_t *vertexCountOut);
Jamie Madilld2b50a02016-06-09 00:13:35 -0700290} // namespace rx
291
292#endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_