1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/TextureD3D.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Buffer.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Config.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Framebuffer.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Image.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Surface.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Texture.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/formatutils.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/BufferImpl.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/BufferD3D.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/ContextD3D.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/EGLImageD3D.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/ImageD3D.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/RenderTargetD3D.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/SurfaceD3D.h"
28*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/TextureStorage.h"
29*8975f5c5SAndroid Build Coastguard Worker
30*8975f5c5SAndroid Build Coastguard Worker namespace rx
31*8975f5c5SAndroid Build Coastguard Worker {
32*8975f5c5SAndroid Build Coastguard Worker
33*8975f5c5SAndroid Build Coastguard Worker namespace
34*8975f5c5SAndroid Build Coastguard Worker {
35*8975f5c5SAndroid Build Coastguard Worker
GetUnpackPointer(const gl::Context * context,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels,ptrdiff_t layerOffset,const uint8_t ** pointerOut)36*8975f5c5SAndroid Build Coastguard Worker angle::Result GetUnpackPointer(const gl::Context *context,
37*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
38*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
39*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels,
40*8975f5c5SAndroid Build Coastguard Worker ptrdiff_t layerOffset,
41*8975f5c5SAndroid Build Coastguard Worker const uint8_t **pointerOut)
42*8975f5c5SAndroid Build Coastguard Worker {
43*8975f5c5SAndroid Build Coastguard Worker if (unpackBuffer)
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not
46*8975f5c5SAndroid Build Coastguard Worker // supported
47*8975f5c5SAndroid Build Coastguard Worker ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
48*8975f5c5SAndroid Build Coastguard Worker
49*8975f5c5SAndroid Build Coastguard Worker // TODO: this is the only place outside of renderer that asks for a buffers raw data.
50*8975f5c5SAndroid Build Coastguard Worker // This functionality should be moved into renderer and the getData method of BufferImpl
51*8975f5c5SAndroid Build Coastguard Worker // removed.
52*8975f5c5SAndroid Build Coastguard Worker BufferD3D *bufferD3D = GetImplAs<BufferD3D>(unpackBuffer);
53*8975f5c5SAndroid Build Coastguard Worker ASSERT(bufferD3D);
54*8975f5c5SAndroid Build Coastguard Worker const uint8_t *bufferData = nullptr;
55*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(bufferD3D->getData(context, &bufferData));
56*8975f5c5SAndroid Build Coastguard Worker *pointerOut = bufferData + offset;
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker else
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker *pointerOut = pixels;
61*8975f5c5SAndroid Build Coastguard Worker }
62*8975f5c5SAndroid Build Coastguard Worker
63*8975f5c5SAndroid Build Coastguard Worker // Offset the pointer for 2D array layer (if it's valid)
64*8975f5c5SAndroid Build Coastguard Worker if (*pointerOut != nullptr)
65*8975f5c5SAndroid Build Coastguard Worker {
66*8975f5c5SAndroid Build Coastguard Worker *pointerOut += layerOffset;
67*8975f5c5SAndroid Build Coastguard Worker }
68*8975f5c5SAndroid Build Coastguard Worker
69*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
70*8975f5c5SAndroid Build Coastguard Worker }
71*8975f5c5SAndroid Build Coastguard Worker
IsRenderTargetUsage(GLenum usage)72*8975f5c5SAndroid Build Coastguard Worker bool IsRenderTargetUsage(GLenum usage)
73*8975f5c5SAndroid Build Coastguard Worker {
74*8975f5c5SAndroid Build Coastguard Worker return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
75*8975f5c5SAndroid Build Coastguard Worker }
76*8975f5c5SAndroid Build Coastguard Worker } // namespace
77*8975f5c5SAndroid Build Coastguard Worker
TextureD3D(const gl::TextureState & state,RendererD3D * renderer)78*8975f5c5SAndroid Build Coastguard Worker TextureD3D::TextureD3D(const gl::TextureState &state, RendererD3D *renderer)
79*8975f5c5SAndroid Build Coastguard Worker : TextureImpl(state),
80*8975f5c5SAndroid Build Coastguard Worker mRenderer(renderer),
81*8975f5c5SAndroid Build Coastguard Worker mDirtyImages(true),
82*8975f5c5SAndroid Build Coastguard Worker mImmutable(false),
83*8975f5c5SAndroid Build Coastguard Worker mTexStorage(nullptr),
84*8975f5c5SAndroid Build Coastguard Worker mTexStorageObserverBinding(this, kTextureStorageObserverMessageIndex),
85*8975f5c5SAndroid Build Coastguard Worker mBaseLevel(0)
86*8975f5c5SAndroid Build Coastguard Worker {}
87*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D()88*8975f5c5SAndroid Build Coastguard Worker TextureD3D::~TextureD3D()
89*8975f5c5SAndroid Build Coastguard Worker {
90*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mTexStorage);
91*8975f5c5SAndroid Build Coastguard Worker }
92*8975f5c5SAndroid Build Coastguard Worker
getNativeTexture(const gl::Context * context,TextureStorage ** outStorage)93*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::getNativeTexture(const gl::Context *context, TextureStorage **outStorage)
94*8975f5c5SAndroid Build Coastguard Worker {
95*8975f5c5SAndroid Build Coastguard Worker // ensure the underlying texture is created
96*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeStorage(context, BindFlags()));
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
99*8975f5c5SAndroid Build Coastguard Worker {
100*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
101*8975f5c5SAndroid Build Coastguard Worker }
102*8975f5c5SAndroid Build Coastguard Worker
103*8975f5c5SAndroid Build Coastguard Worker ASSERT(outStorage);
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker *outStorage = mTexStorage;
106*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker
getImageAndSyncFromStorage(const gl::Context * context,const gl::ImageIndex & index,ImageD3D ** outImage)109*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::getImageAndSyncFromStorage(const gl::Context *context,
110*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
111*8975f5c5SAndroid Build Coastguard Worker ImageD3D **outImage)
112*8975f5c5SAndroid Build Coastguard Worker {
113*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
114*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage && mTexStorage->isRenderTarget())
115*8975f5c5SAndroid Build Coastguard Worker {
116*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->copyFromTexStorage(context, index, mTexStorage));
117*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
118*8975f5c5SAndroid Build Coastguard Worker }
119*8975f5c5SAndroid Build Coastguard Worker image->markClean();
120*8975f5c5SAndroid Build Coastguard Worker *outImage = image;
121*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
122*8975f5c5SAndroid Build Coastguard Worker }
123*8975f5c5SAndroid Build Coastguard Worker
getLevelZeroWidth() const124*8975f5c5SAndroid Build Coastguard Worker GLint TextureD3D::getLevelZeroWidth() const
125*8975f5c5SAndroid Build Coastguard Worker {
126*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::CountLeadingZeros(static_cast<uint32_t>(getBaseLevelWidth())) > getBaseLevel());
127*8975f5c5SAndroid Build Coastguard Worker return getBaseLevelWidth() << mBaseLevel;
128*8975f5c5SAndroid Build Coastguard Worker }
129*8975f5c5SAndroid Build Coastguard Worker
getLevelZeroHeight() const130*8975f5c5SAndroid Build Coastguard Worker GLint TextureD3D::getLevelZeroHeight() const
131*8975f5c5SAndroid Build Coastguard Worker {
132*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::CountLeadingZeros(static_cast<uint32_t>(getBaseLevelHeight())) > getBaseLevel());
133*8975f5c5SAndroid Build Coastguard Worker return getBaseLevelHeight() << mBaseLevel;
134*8975f5c5SAndroid Build Coastguard Worker }
135*8975f5c5SAndroid Build Coastguard Worker
getLevelZeroDepth() const136*8975f5c5SAndroid Build Coastguard Worker GLint TextureD3D::getLevelZeroDepth() const
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker return getBaseLevelDepth();
139*8975f5c5SAndroid Build Coastguard Worker }
140*8975f5c5SAndroid Build Coastguard Worker
getBaseLevelWidth() const141*8975f5c5SAndroid Build Coastguard Worker GLint TextureD3D::getBaseLevelWidth() const
142*8975f5c5SAndroid Build Coastguard Worker {
143*8975f5c5SAndroid Build Coastguard Worker const ImageD3D *baseImage = getBaseLevelImage();
144*8975f5c5SAndroid Build Coastguard Worker return (baseImage ? baseImage->getWidth() : 0);
145*8975f5c5SAndroid Build Coastguard Worker }
146*8975f5c5SAndroid Build Coastguard Worker
getBaseLevelHeight() const147*8975f5c5SAndroid Build Coastguard Worker GLint TextureD3D::getBaseLevelHeight() const
148*8975f5c5SAndroid Build Coastguard Worker {
149*8975f5c5SAndroid Build Coastguard Worker const ImageD3D *baseImage = getBaseLevelImage();
150*8975f5c5SAndroid Build Coastguard Worker return (baseImage ? baseImage->getHeight() : 0);
151*8975f5c5SAndroid Build Coastguard Worker }
152*8975f5c5SAndroid Build Coastguard Worker
getBaseLevelDepth() const153*8975f5c5SAndroid Build Coastguard Worker GLint TextureD3D::getBaseLevelDepth() const
154*8975f5c5SAndroid Build Coastguard Worker {
155*8975f5c5SAndroid Build Coastguard Worker const ImageD3D *baseImage = getBaseLevelImage();
156*8975f5c5SAndroid Build Coastguard Worker return (baseImage ? baseImage->getDepth() : 0);
157*8975f5c5SAndroid Build Coastguard Worker }
158*8975f5c5SAndroid Build Coastguard Worker
159*8975f5c5SAndroid Build Coastguard Worker // Note: "base level image" is loosely defined to be any image from the base level,
160*8975f5c5SAndroid Build Coastguard Worker // where in the base of 2D array textures and cube maps there are several. Don't use
161*8975f5c5SAndroid Build Coastguard Worker // the base level image for anything except querying texture format and size.
getBaseLevelInternalFormat() const162*8975f5c5SAndroid Build Coastguard Worker GLenum TextureD3D::getBaseLevelInternalFormat() const
163*8975f5c5SAndroid Build Coastguard Worker {
164*8975f5c5SAndroid Build Coastguard Worker const ImageD3D *baseImage = getBaseLevelImage();
165*8975f5c5SAndroid Build Coastguard Worker return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
166*8975f5c5SAndroid Build Coastguard Worker }
167*8975f5c5SAndroid Build Coastguard Worker
setStorage(const gl::Context * context,gl::TextureType type,size_t levels,GLenum internalFormat,const gl::Extents & size)168*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::setStorage(const gl::Context *context,
169*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
170*8975f5c5SAndroid Build Coastguard Worker size_t levels,
171*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
172*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size)
173*8975f5c5SAndroid Build Coastguard Worker {
174*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
175*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker
setStorageMultisample(const gl::Context * context,gl::TextureType type,GLsizei samples,GLint internalformat,const gl::Extents & size,bool fixedSampleLocations)178*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::setStorageMultisample(const gl::Context *context,
179*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
180*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
181*8975f5c5SAndroid Build Coastguard Worker GLint internalformat,
182*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
183*8975f5c5SAndroid Build Coastguard Worker bool fixedSampleLocations)
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
186*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
187*8975f5c5SAndroid Build Coastguard Worker }
188*8975f5c5SAndroid Build Coastguard Worker
setBuffer(const gl::Context * context,GLenum internalFormat)189*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::setBuffer(const gl::Context *context, GLenum internalFormat)
190*8975f5c5SAndroid Build Coastguard Worker {
191*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
192*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
193*8975f5c5SAndroid Build Coastguard Worker }
194*8975f5c5SAndroid Build Coastguard Worker
setStorageExternalMemory(const gl::Context * context,gl::TextureType type,size_t levels,GLenum internalFormat,const gl::Extents & size,gl::MemoryObject * memoryObject,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)195*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::setStorageExternalMemory(const gl::Context *context,
196*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
197*8975f5c5SAndroid Build Coastguard Worker size_t levels,
198*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
199*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
200*8975f5c5SAndroid Build Coastguard Worker gl::MemoryObject *memoryObject,
201*8975f5c5SAndroid Build Coastguard Worker GLuint64 offset,
202*8975f5c5SAndroid Build Coastguard Worker GLbitfield createFlags,
203*8975f5c5SAndroid Build Coastguard Worker GLbitfield usageFlags,
204*8975f5c5SAndroid Build Coastguard Worker const void *imageCreateInfoPNext)
205*8975f5c5SAndroid Build Coastguard Worker {
206*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
207*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker
shouldUseSetData(const ImageD3D * image) const210*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D::shouldUseSetData(const ImageD3D *image) const
211*8975f5c5SAndroid Build Coastguard Worker {
212*8975f5c5SAndroid Build Coastguard Worker if (!mRenderer->getFeatures().setDataFasterThanImageUpload.enabled)
213*8975f5c5SAndroid Build Coastguard Worker {
214*8975f5c5SAndroid Build Coastguard Worker return false;
215*8975f5c5SAndroid Build Coastguard Worker }
216*8975f5c5SAndroid Build Coastguard Worker
217*8975f5c5SAndroid Build Coastguard Worker if (image->isDirty())
218*8975f5c5SAndroid Build Coastguard Worker {
219*8975f5c5SAndroid Build Coastguard Worker return false;
220*8975f5c5SAndroid Build Coastguard Worker }
221*8975f5c5SAndroid Build Coastguard Worker
222*8975f5c5SAndroid Build Coastguard Worker gl::InternalFormat internalFormat = gl::GetSizedInternalFormatInfo(image->getInternalFormat());
223*8975f5c5SAndroid Build Coastguard Worker
224*8975f5c5SAndroid Build Coastguard Worker // We can only handle full updates for depth-stencil textures, so to avoid complications
225*8975f5c5SAndroid Build Coastguard Worker // disable them entirely.
226*8975f5c5SAndroid Build Coastguard Worker if (internalFormat.depthBits > 0 || internalFormat.stencilBits > 0)
227*8975f5c5SAndroid Build Coastguard Worker {
228*8975f5c5SAndroid Build Coastguard Worker return false;
229*8975f5c5SAndroid Build Coastguard Worker }
230*8975f5c5SAndroid Build Coastguard Worker
231*8975f5c5SAndroid Build Coastguard Worker // TODO(jmadill): Handle compressed internal formats
232*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage && !internalFormat.compressed);
233*8975f5c5SAndroid Build Coastguard Worker }
234*8975f5c5SAndroid Build Coastguard Worker
setImageImpl(const gl::Context * context,const gl::ImageIndex & index,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels,ptrdiff_t layerOffset)235*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::setImageImpl(const gl::Context *context,
236*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
237*8975f5c5SAndroid Build Coastguard Worker GLenum type,
238*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
239*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
240*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels,
241*8975f5c5SAndroid Build Coastguard Worker ptrdiff_t layerOffset)
242*8975f5c5SAndroid Build Coastguard Worker {
243*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
244*8975f5c5SAndroid Build Coastguard Worker ASSERT(image);
245*8975f5c5SAndroid Build Coastguard Worker
246*8975f5c5SAndroid Build Coastguard Worker // No-op
247*8975f5c5SAndroid Build Coastguard Worker if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
248*8975f5c5SAndroid Build Coastguard Worker {
249*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
250*8975f5c5SAndroid Build Coastguard Worker }
251*8975f5c5SAndroid Build Coastguard Worker
252*8975f5c5SAndroid Build Coastguard Worker // We no longer need the "GLenum format" parameter to TexImage to determine what data format
253*8975f5c5SAndroid Build Coastguard Worker // "pixels" contains. From our image internal format we know how many channels to expect, and
254*8975f5c5SAndroid Build Coastguard Worker // "type" gives the format of pixel's components.
255*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixelData = nullptr;
256*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
257*8975f5c5SAndroid Build Coastguard Worker
258*8975f5c5SAndroid Build Coastguard Worker if (pixelData != nullptr)
259*8975f5c5SAndroid Build Coastguard Worker {
260*8975f5c5SAndroid Build Coastguard Worker if (shouldUseSetData(image))
261*8975f5c5SAndroid Build Coastguard Worker {
262*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
263*8975f5c5SAndroid Build Coastguard Worker mTexStorage->setData(context, index, image, nullptr, type, unpack, pixelData));
264*8975f5c5SAndroid Build Coastguard Worker }
265*8975f5c5SAndroid Build Coastguard Worker else
266*8975f5c5SAndroid Build Coastguard Worker {
267*8975f5c5SAndroid Build Coastguard Worker gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(),
268*8975f5c5SAndroid Build Coastguard Worker image->getDepth());
269*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->loadData(context, fullImageArea, unpack, type, pixelData,
270*8975f5c5SAndroid Build Coastguard Worker index.usesTex3D()));
271*8975f5c5SAndroid Build Coastguard Worker }
272*8975f5c5SAndroid Build Coastguard Worker
273*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
274*8975f5c5SAndroid Build Coastguard Worker }
275*8975f5c5SAndroid Build Coastguard Worker
276*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
277*8975f5c5SAndroid Build Coastguard Worker }
278*8975f5c5SAndroid Build Coastguard Worker
subImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels,ptrdiff_t layerOffset)279*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::subImage(const gl::Context *context,
280*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
281*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
282*8975f5c5SAndroid Build Coastguard Worker GLenum format,
283*8975f5c5SAndroid Build Coastguard Worker GLenum type,
284*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
285*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
286*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels,
287*8975f5c5SAndroid Build Coastguard Worker ptrdiff_t layerOffset)
288*8975f5c5SAndroid Build Coastguard Worker {
289*8975f5c5SAndroid Build Coastguard Worker // CPU readback & copy where direct GPU copy is not supported
290*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixelData = nullptr;
291*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
292*8975f5c5SAndroid Build Coastguard Worker
293*8975f5c5SAndroid Build Coastguard Worker if (pixelData != nullptr)
294*8975f5c5SAndroid Build Coastguard Worker {
295*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
296*8975f5c5SAndroid Build Coastguard Worker ASSERT(image);
297*8975f5c5SAndroid Build Coastguard Worker
298*8975f5c5SAndroid Build Coastguard Worker if (shouldUseSetData(image) && !mTexStorage->isMultiplanar(context))
299*8975f5c5SAndroid Build Coastguard Worker {
300*8975f5c5SAndroid Build Coastguard Worker return mTexStorage->setData(context, index, image, &area, type, unpack, pixelData);
301*8975f5c5SAndroid Build Coastguard Worker }
302*8975f5c5SAndroid Build Coastguard Worker
303*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->loadData(context, area, unpack, type, pixelData, index.usesTex3D()));
304*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, area));
305*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
306*8975f5c5SAndroid Build Coastguard Worker }
307*8975f5c5SAndroid Build Coastguard Worker
308*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
309*8975f5c5SAndroid Build Coastguard Worker }
310*8975f5c5SAndroid Build Coastguard Worker
setCompressedImageImpl(const gl::Context * context,const gl::ImageIndex & index,const gl::PixelUnpackState & unpack,const uint8_t * pixels,ptrdiff_t layerOffset)311*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::setCompressedImageImpl(const gl::Context *context,
312*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
313*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
314*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels,
315*8975f5c5SAndroid Build Coastguard Worker ptrdiff_t layerOffset)
316*8975f5c5SAndroid Build Coastguard Worker {
317*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
318*8975f5c5SAndroid Build Coastguard Worker ASSERT(image);
319*8975f5c5SAndroid Build Coastguard Worker
320*8975f5c5SAndroid Build Coastguard Worker if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
321*8975f5c5SAndroid Build Coastguard Worker {
322*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
323*8975f5c5SAndroid Build Coastguard Worker }
324*8975f5c5SAndroid Build Coastguard Worker
325*8975f5c5SAndroid Build Coastguard Worker // We no longer need the "GLenum format" parameter to TexImage to determine what data format
326*8975f5c5SAndroid Build Coastguard Worker // "pixels" contains. From our image internal format we know how many channels to expect, and
327*8975f5c5SAndroid Build Coastguard Worker // "type" gives the format of pixel's components.
328*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixelData = nullptr;
329*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
330*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
331*8975f5c5SAndroid Build Coastguard Worker
332*8975f5c5SAndroid Build Coastguard Worker if (pixelData != nullptr)
333*8975f5c5SAndroid Build Coastguard Worker {
334*8975f5c5SAndroid Build Coastguard Worker gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
335*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->loadCompressedData(context, fullImageArea, pixelData));
336*8975f5c5SAndroid Build Coastguard Worker
337*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
338*8975f5c5SAndroid Build Coastguard Worker }
339*8975f5c5SAndroid Build Coastguard Worker
340*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
341*8975f5c5SAndroid Build Coastguard Worker }
342*8975f5c5SAndroid Build Coastguard Worker
subImageCompressed(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,const gl::PixelUnpackState & unpack,const uint8_t * pixels,ptrdiff_t layerOffset)343*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::subImageCompressed(const gl::Context *context,
344*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
345*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
346*8975f5c5SAndroid Build Coastguard Worker GLenum format,
347*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
348*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels,
349*8975f5c5SAndroid Build Coastguard Worker ptrdiff_t layerOffset)
350*8975f5c5SAndroid Build Coastguard Worker {
351*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixelData = nullptr;
352*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
353*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
354*8975f5c5SAndroid Build Coastguard Worker
355*8975f5c5SAndroid Build Coastguard Worker if (pixelData != nullptr)
356*8975f5c5SAndroid Build Coastguard Worker {
357*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
358*8975f5c5SAndroid Build Coastguard Worker ASSERT(image);
359*8975f5c5SAndroid Build Coastguard Worker
360*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->loadCompressedData(context, area, pixelData));
361*8975f5c5SAndroid Build Coastguard Worker
362*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
363*8975f5c5SAndroid Build Coastguard Worker }
364*8975f5c5SAndroid Build Coastguard Worker
365*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
366*8975f5c5SAndroid Build Coastguard Worker }
367*8975f5c5SAndroid Build Coastguard Worker
isFastUnpackable(const gl::Buffer * unpackBuffer,const gl::PixelUnpackState & unpack,GLenum sizedInternalFormat)368*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D::isFastUnpackable(const gl::Buffer *unpackBuffer,
369*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
370*8975f5c5SAndroid Build Coastguard Worker GLenum sizedInternalFormat)
371*8975f5c5SAndroid Build Coastguard Worker {
372*8975f5c5SAndroid Build Coastguard Worker return unpackBuffer != nullptr && unpack.skipRows == 0 && unpack.skipPixels == 0 &&
373*8975f5c5SAndroid Build Coastguard Worker unpack.imageHeight == 0 && unpack.skipImages == 0 &&
374*8975f5c5SAndroid Build Coastguard Worker mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
375*8975f5c5SAndroid Build Coastguard Worker }
376*8975f5c5SAndroid Build Coastguard Worker
fastUnpackPixels(const gl::Context * context,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels,const gl::Box & destArea,GLenum sizedInternalFormat,GLenum type,RenderTargetD3D * destRenderTarget)377*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::fastUnpackPixels(const gl::Context *context,
378*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
379*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
380*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels,
381*8975f5c5SAndroid Build Coastguard Worker const gl::Box &destArea,
382*8975f5c5SAndroid Build Coastguard Worker GLenum sizedInternalFormat,
383*8975f5c5SAndroid Build Coastguard Worker GLenum type,
384*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *destRenderTarget)
385*8975f5c5SAndroid Build Coastguard Worker {
386*8975f5c5SAndroid Build Coastguard Worker bool check = (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 ||
387*8975f5c5SAndroid Build Coastguard Worker unpack.skipImages != 0);
388*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK(GetImplAs<ContextD3D>(context), !check,
389*8975f5c5SAndroid Build Coastguard Worker "Unimplemented pixel store parameters in fastUnpackPixels", GL_INVALID_OPERATION);
390*8975f5c5SAndroid Build Coastguard Worker
391*8975f5c5SAndroid Build Coastguard Worker // No-op
392*8975f5c5SAndroid Build Coastguard Worker if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
393*8975f5c5SAndroid Build Coastguard Worker {
394*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
395*8975f5c5SAndroid Build Coastguard Worker }
396*8975f5c5SAndroid Build Coastguard Worker
397*8975f5c5SAndroid Build Coastguard Worker // In order to perform the fast copy through the shader, we must have the right format, and be
398*8975f5c5SAndroid Build Coastguard Worker // able to create a render target.
399*8975f5c5SAndroid Build Coastguard Worker ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat));
400*8975f5c5SAndroid Build Coastguard Worker
401*8975f5c5SAndroid Build Coastguard Worker uintptr_t offset = reinterpret_cast<uintptr_t>(pixels);
402*8975f5c5SAndroid Build Coastguard Worker
403*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->fastCopyBufferToTexture(
404*8975f5c5SAndroid Build Coastguard Worker context, unpack, unpackBuffer, static_cast<unsigned int>(offset), destRenderTarget,
405*8975f5c5SAndroid Build Coastguard Worker sizedInternalFormat, type, destArea));
406*8975f5c5SAndroid Build Coastguard Worker
407*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
408*8975f5c5SAndroid Build Coastguard Worker }
409*8975f5c5SAndroid Build Coastguard Worker
creationLevels(GLsizei width,GLsizei height,GLsizei depth) const410*8975f5c5SAndroid Build Coastguard Worker GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const
411*8975f5c5SAndroid Build Coastguard Worker {
412*8975f5c5SAndroid Build Coastguard Worker if ((gl::isPow2(width) && gl::isPow2(height) && gl::isPow2(depth)) ||
413*8975f5c5SAndroid Build Coastguard Worker mRenderer->getNativeExtensions().textureNpotOES)
414*8975f5c5SAndroid Build Coastguard Worker {
415*8975f5c5SAndroid Build Coastguard Worker // Maximum number of levels
416*8975f5c5SAndroid Build Coastguard Worker return gl::log2(std::max({width, height, depth})) + 1;
417*8975f5c5SAndroid Build Coastguard Worker }
418*8975f5c5SAndroid Build Coastguard Worker else
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 2.0 without GL_OES_texture_npot does not permit NPOT mipmaps.
421*8975f5c5SAndroid Build Coastguard Worker return 1;
422*8975f5c5SAndroid Build Coastguard Worker }
423*8975f5c5SAndroid Build Coastguard Worker }
424*8975f5c5SAndroid Build Coastguard Worker
getStorage()425*8975f5c5SAndroid Build Coastguard Worker TextureStorage *TextureD3D::getStorage()
426*8975f5c5SAndroid Build Coastguard Worker {
427*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
428*8975f5c5SAndroid Build Coastguard Worker return mTexStorage;
429*8975f5c5SAndroid Build Coastguard Worker }
430*8975f5c5SAndroid Build Coastguard Worker
getBaseLevelImage() const431*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D::getBaseLevelImage() const
432*8975f5c5SAndroid Build Coastguard Worker {
433*8975f5c5SAndroid Build Coastguard Worker if (mBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
434*8975f5c5SAndroid Build Coastguard Worker {
435*8975f5c5SAndroid Build Coastguard Worker return nullptr;
436*8975f5c5SAndroid Build Coastguard Worker }
437*8975f5c5SAndroid Build Coastguard Worker return getImage(getImageIndex(mBaseLevel, 0));
438*8975f5c5SAndroid Build Coastguard Worker }
439*8975f5c5SAndroid Build Coastguard Worker
setImageExternal(const gl::Context * context,gl::TextureType type,egl::Stream * stream,const egl::Stream::GLTextureDescription & desc)440*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::setImageExternal(const gl::Context *context,
441*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
442*8975f5c5SAndroid Build Coastguard Worker egl::Stream *stream,
443*8975f5c5SAndroid Build Coastguard Worker const egl::Stream::GLTextureDescription &desc)
444*8975f5c5SAndroid Build Coastguard Worker {
445*8975f5c5SAndroid Build Coastguard Worker // Only external images can accept external textures
446*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
447*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
448*8975f5c5SAndroid Build Coastguard Worker }
449*8975f5c5SAndroid Build Coastguard Worker
generateMipmap(const gl::Context * context)450*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::generateMipmap(const gl::Context *context)
451*8975f5c5SAndroid Build Coastguard Worker {
452*8975f5c5SAndroid Build Coastguard Worker const GLuint baseLevel = mState.getEffectiveBaseLevel();
453*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = mState.getMipmapMaxLevel();
454*8975f5c5SAndroid Build Coastguard Worker ASSERT(maxLevel > baseLevel); // Should be checked before calling this.
455*8975f5c5SAndroid Build Coastguard Worker
456*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
457*8975f5c5SAndroid Build Coastguard Worker {
458*8975f5c5SAndroid Build Coastguard Worker // Switch to using the mipmapped texture.
459*8975f5c5SAndroid Build Coastguard Worker TextureStorage *textureStorageEXT = nullptr;
460*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getNativeTexture(context, &textureStorageEXT));
461*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(textureStorageEXT->useLevelZeroWorkaroundTexture(context, false));
462*8975f5c5SAndroid Build Coastguard Worker }
463*8975f5c5SAndroid Build Coastguard Worker
464*8975f5c5SAndroid Build Coastguard Worker // Set up proper mipmap chain in our Image array.
465*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initMipmapImages(context));
466*8975f5c5SAndroid Build Coastguard Worker
467*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage && mTexStorage->supportsNativeMipmapFunction())
468*8975f5c5SAndroid Build Coastguard Worker {
469*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
470*8975f5c5SAndroid Build Coastguard Worker
471*8975f5c5SAndroid Build Coastguard Worker // Generate the mipmap chain using the ad-hoc DirectX function.
472*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->generateMipmapUsingD3D(context, mTexStorage, mState));
473*8975f5c5SAndroid Build Coastguard Worker }
474*8975f5c5SAndroid Build Coastguard Worker else
475*8975f5c5SAndroid Build Coastguard Worker {
476*8975f5c5SAndroid Build Coastguard Worker // Generate the mipmap chain, one level at a time.
477*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(generateMipmapUsingImages(context, maxLevel));
478*8975f5c5SAndroid Build Coastguard Worker }
479*8975f5c5SAndroid Build Coastguard Worker
480*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
481*8975f5c5SAndroid Build Coastguard Worker }
482*8975f5c5SAndroid Build Coastguard Worker
generateMipmapUsingImages(const gl::Context * context,const GLuint maxLevel)483*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::generateMipmapUsingImages(const gl::Context *context,
484*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel)
485*8975f5c5SAndroid Build Coastguard Worker {
486*8975f5c5SAndroid Build Coastguard Worker // We know that all layers have the same dimension, for the texture to be complete
487*8975f5c5SAndroid Build Coastguard Worker GLint layerCount = static_cast<GLint>(getLayerCount(mBaseLevel));
488*8975f5c5SAndroid Build Coastguard Worker
489*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage && !mTexStorage->isRenderTarget() &&
490*8975f5c5SAndroid Build Coastguard Worker canCreateRenderTargetForImage(getImageIndex(mBaseLevel, 0)) &&
491*8975f5c5SAndroid Build Coastguard Worker mRenderer->getRendererClass() == RENDERER_D3D11)
492*8975f5c5SAndroid Build Coastguard Worker {
493*8975f5c5SAndroid Build Coastguard Worker if (!mRenderer->getFeatures().setDataFasterThanImageUpload.enabled)
494*8975f5c5SAndroid Build Coastguard Worker {
495*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
498*8975f5c5SAndroid Build Coastguard Worker }
499*8975f5c5SAndroid Build Coastguard Worker else if (mRenderer->getFeatures().setDataFasterThanImageUpload.enabled && mTexStorage)
500*8975f5c5SAndroid Build Coastguard Worker {
501*8975f5c5SAndroid Build Coastguard Worker // When making mipmaps with the setData workaround enabled, the texture storage has
502*8975f5c5SAndroid Build Coastguard Worker // the image data already. For non-render-target storage, we have to pull it out into
503*8975f5c5SAndroid Build Coastguard Worker // an image layer.
504*8975f5c5SAndroid Build Coastguard Worker if (!mTexStorage->isRenderTarget())
505*8975f5c5SAndroid Build Coastguard Worker {
506*8975f5c5SAndroid Build Coastguard Worker // Copy from the storage mip 0 to Image mip 0
507*8975f5c5SAndroid Build Coastguard Worker for (GLint layer = 0; layer < layerCount; ++layer)
508*8975f5c5SAndroid Build Coastguard Worker {
509*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex srcIndex = getImageIndex(mBaseLevel, layer);
510*8975f5c5SAndroid Build Coastguard Worker
511*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(srcIndex);
512*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->copyFromTexStorage(context, srcIndex, mTexStorage));
513*8975f5c5SAndroid Build Coastguard Worker }
514*8975f5c5SAndroid Build Coastguard Worker }
515*8975f5c5SAndroid Build Coastguard Worker else
516*8975f5c5SAndroid Build Coastguard Worker {
517*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
518*8975f5c5SAndroid Build Coastguard Worker }
519*8975f5c5SAndroid Build Coastguard Worker }
520*8975f5c5SAndroid Build Coastguard Worker
521*8975f5c5SAndroid Build Coastguard Worker // TODO: Decouple this from zeroMaxLodWorkaround. This is a 9_3 restriction, unrelated to
522*8975f5c5SAndroid Build Coastguard Worker // zeroMaxLodWorkaround. The restriction is because Feature Level 9_3 can't create SRVs on
523*8975f5c5SAndroid Build Coastguard Worker // individual levels of the texture. As a result, even if the storage is a rendertarget, we
524*8975f5c5SAndroid Build Coastguard Worker // can't use the GPU to generate the mipmaps without further work. The D3D9 renderer works
525*8975f5c5SAndroid Build Coastguard Worker // around this by copying each level of the texture into its own single-layer GPU texture (in
526*8975f5c5SAndroid Build Coastguard Worker // Blit9::boxFilter). Feature Level 9_3 could do something similar, or it could continue to use
527*8975f5c5SAndroid Build Coastguard Worker // CPU-side mipmap generation, or something else.
528*8975f5c5SAndroid Build Coastguard Worker bool renderableStorage = (mTexStorage && mTexStorage->isRenderTarget() &&
529*8975f5c5SAndroid Build Coastguard Worker !(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled));
530*8975f5c5SAndroid Build Coastguard Worker if (renderableStorage)
531*8975f5c5SAndroid Build Coastguard Worker {
532*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
533*8975f5c5SAndroid Build Coastguard Worker }
534*8975f5c5SAndroid Build Coastguard Worker
535*8975f5c5SAndroid Build Coastguard Worker for (GLint layer = 0; layer < layerCount; ++layer)
536*8975f5c5SAndroid Build Coastguard Worker {
537*8975f5c5SAndroid Build Coastguard Worker for (GLuint mip = mBaseLevel + 1; mip <= maxLevel; ++mip)
538*8975f5c5SAndroid Build Coastguard Worker {
539*8975f5c5SAndroid Build Coastguard Worker ASSERT(getLayerCount(mip) == layerCount);
540*8975f5c5SAndroid Build Coastguard Worker
541*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex sourceIndex = getImageIndex(mip - 1, layer);
542*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex destIndex = getImageIndex(mip, layer);
543*8975f5c5SAndroid Build Coastguard Worker
544*8975f5c5SAndroid Build Coastguard Worker if (renderableStorage)
545*8975f5c5SAndroid Build Coastguard Worker {
546*8975f5c5SAndroid Build Coastguard Worker // GPU-side mipmapping
547*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexStorage->generateMipmap(context, sourceIndex, destIndex));
548*8975f5c5SAndroid Build Coastguard Worker }
549*8975f5c5SAndroid Build Coastguard Worker else
550*8975f5c5SAndroid Build Coastguard Worker {
551*8975f5c5SAndroid Build Coastguard Worker // CPU-side mipmapping
552*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
553*8975f5c5SAndroid Build Coastguard Worker mRenderer->generateMipmap(context, getImage(destIndex), getImage(sourceIndex)));
554*8975f5c5SAndroid Build Coastguard Worker }
555*8975f5c5SAndroid Build Coastguard Worker }
556*8975f5c5SAndroid Build Coastguard Worker }
557*8975f5c5SAndroid Build Coastguard Worker
558*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = !renderableStorage;
559*8975f5c5SAndroid Build Coastguard Worker
560*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage && mDirtyImages)
561*8975f5c5SAndroid Build Coastguard Worker {
562*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
563*8975f5c5SAndroid Build Coastguard Worker }
564*8975f5c5SAndroid Build Coastguard Worker
565*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
566*8975f5c5SAndroid Build Coastguard Worker }
567*8975f5c5SAndroid Build Coastguard Worker
isBaseImageZeroSize() const568*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D::isBaseImageZeroSize() const
569*8975f5c5SAndroid Build Coastguard Worker {
570*8975f5c5SAndroid Build Coastguard Worker ImageD3D *baseImage = getBaseLevelImage();
571*8975f5c5SAndroid Build Coastguard Worker
572*8975f5c5SAndroid Build Coastguard Worker if (!baseImage || baseImage->getWidth() <= 0 || baseImage->getHeight() <= 0)
573*8975f5c5SAndroid Build Coastguard Worker {
574*8975f5c5SAndroid Build Coastguard Worker return true;
575*8975f5c5SAndroid Build Coastguard Worker }
576*8975f5c5SAndroid Build Coastguard Worker
577*8975f5c5SAndroid Build Coastguard Worker if (baseImage->getType() == gl::TextureType::_3D && baseImage->getDepth() <= 0)
578*8975f5c5SAndroid Build Coastguard Worker {
579*8975f5c5SAndroid Build Coastguard Worker return true;
580*8975f5c5SAndroid Build Coastguard Worker }
581*8975f5c5SAndroid Build Coastguard Worker
582*8975f5c5SAndroid Build Coastguard Worker if (baseImage->getType() == gl::TextureType::_2DArray && getLayerCount(getBaseLevel()) <= 0)
583*8975f5c5SAndroid Build Coastguard Worker {
584*8975f5c5SAndroid Build Coastguard Worker return true;
585*8975f5c5SAndroid Build Coastguard Worker }
586*8975f5c5SAndroid Build Coastguard Worker
587*8975f5c5SAndroid Build Coastguard Worker return false;
588*8975f5c5SAndroid Build Coastguard Worker }
589*8975f5c5SAndroid Build Coastguard Worker
ensureBindFlags(const gl::Context * context,BindFlags bindFlags)590*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::ensureBindFlags(const gl::Context *context, BindFlags bindFlags)
591*8975f5c5SAndroid Build Coastguard Worker {
592*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeStorage(context, bindFlags));
593*8975f5c5SAndroid Build Coastguard Worker
594*8975f5c5SAndroid Build Coastguard Worker // initializeStorage can fail with NoError if the texture is not complete. This is not
595*8975f5c5SAndroid Build Coastguard Worker // an error for incomplete sampling, but it is a big problem for rendering.
596*8975f5c5SAndroid Build Coastguard Worker if (!mTexStorage)
597*8975f5c5SAndroid Build Coastguard Worker {
598*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
599*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
600*8975f5c5SAndroid Build Coastguard Worker }
601*8975f5c5SAndroid Build Coastguard Worker
602*8975f5c5SAndroid Build Coastguard Worker if (!isBaseImageZeroSize())
603*8975f5c5SAndroid Build Coastguard Worker {
604*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
605*8975f5c5SAndroid Build Coastguard Worker if ((bindFlags.renderTarget && !mTexStorage->isRenderTarget()) ||
606*8975f5c5SAndroid Build Coastguard Worker (bindFlags.unorderedAccess && !mTexStorage->isUnorderedAccess()))
607*8975f5c5SAndroid Build Coastguard Worker {
608*8975f5c5SAndroid Build Coastguard Worker // Preserve all the texture's previous bind flags when creating a new storage.
609*8975f5c5SAndroid Build Coastguard Worker BindFlags newBindFlags = bindFlags;
610*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage->isRenderTarget())
611*8975f5c5SAndroid Build Coastguard Worker {
612*8975f5c5SAndroid Build Coastguard Worker newBindFlags.renderTarget = true;
613*8975f5c5SAndroid Build Coastguard Worker }
614*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage->isUnorderedAccess())
615*8975f5c5SAndroid Build Coastguard Worker {
616*8975f5c5SAndroid Build Coastguard Worker newBindFlags.unorderedAccess = true;
617*8975f5c5SAndroid Build Coastguard Worker }
618*8975f5c5SAndroid Build Coastguard Worker
619*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer newStorage;
620*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(createCompleteStorage(context, newBindFlags, &newStorage));
621*8975f5c5SAndroid Build Coastguard Worker
622*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexStorage->copyToStorage(context, newStorage.get()));
623*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, newStorage.get()));
624*8975f5c5SAndroid Build Coastguard Worker newStorage.release();
625*8975f5c5SAndroid Build Coastguard Worker // If this texture is used in compute shader, we should invalidate this texture so that
626*8975f5c5SAndroid Build Coastguard Worker // the UAV/SRV is rebound again with this new texture storage in next dispatch call.
627*8975f5c5SAndroid Build Coastguard Worker mTexStorage->invalidateTextures();
628*8975f5c5SAndroid Build Coastguard Worker }
629*8975f5c5SAndroid Build Coastguard Worker }
630*8975f5c5SAndroid Build Coastguard Worker
631*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
632*8975f5c5SAndroid Build Coastguard Worker }
633*8975f5c5SAndroid Build Coastguard Worker
ensureRenderTarget(const gl::Context * context)634*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::ensureRenderTarget(const gl::Context *context)
635*8975f5c5SAndroid Build Coastguard Worker {
636*8975f5c5SAndroid Build Coastguard Worker return ensureBindFlags(context, BindFlags::RenderTarget());
637*8975f5c5SAndroid Build Coastguard Worker }
638*8975f5c5SAndroid Build Coastguard Worker
ensureUnorderedAccess(const gl::Context * context)639*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::ensureUnorderedAccess(const gl::Context *context)
640*8975f5c5SAndroid Build Coastguard Worker {
641*8975f5c5SAndroid Build Coastguard Worker return ensureBindFlags(context, BindFlags::UnorderedAccess());
642*8975f5c5SAndroid Build Coastguard Worker }
643*8975f5c5SAndroid Build Coastguard Worker
canCreateRenderTargetForImage(const gl::ImageIndex & index) const644*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const
645*8975f5c5SAndroid Build Coastguard Worker {
646*8975f5c5SAndroid Build Coastguard Worker if (index.getType() == gl::TextureType::_2DMultisample ||
647*8975f5c5SAndroid Build Coastguard Worker index.getType() == gl::TextureType::_2DMultisampleArray)
648*8975f5c5SAndroid Build Coastguard Worker {
649*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getType() != gl::TextureType::_2DMultisampleArray || index.hasLayer());
650*8975f5c5SAndroid Build Coastguard Worker return true;
651*8975f5c5SAndroid Build Coastguard Worker }
652*8975f5c5SAndroid Build Coastguard Worker
653*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
654*8975f5c5SAndroid Build Coastguard Worker ASSERT(image);
655*8975f5c5SAndroid Build Coastguard Worker bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0)));
656*8975f5c5SAndroid Build Coastguard Worker return (image->isRenderableFormat() && levelsComplete);
657*8975f5c5SAndroid Build Coastguard Worker }
658*8975f5c5SAndroid Build Coastguard Worker
commitRegion(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & region)659*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::commitRegion(const gl::Context *context,
660*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
661*8975f5c5SAndroid Build Coastguard Worker const gl::Box ®ion)
662*8975f5c5SAndroid Build Coastguard Worker {
663*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
664*8975f5c5SAndroid Build Coastguard Worker {
665*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidIndex(index));
666*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
667*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->copyToStorage(context, mTexStorage, index, region));
668*8975f5c5SAndroid Build Coastguard Worker image->markClean();
669*8975f5c5SAndroid Build Coastguard Worker }
670*8975f5c5SAndroid Build Coastguard Worker
671*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
672*8975f5c5SAndroid Build Coastguard Worker }
673*8975f5c5SAndroid Build Coastguard Worker
getAttachmentRenderTarget(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex,GLsizei samples,FramebufferAttachmentRenderTarget ** rtOut)674*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::getAttachmentRenderTarget(const gl::Context *context,
675*8975f5c5SAndroid Build Coastguard Worker GLenum binding,
676*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &imageIndex,
677*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
678*8975f5c5SAndroid Build Coastguard Worker FramebufferAttachmentRenderTarget **rtOut)
679*8975f5c5SAndroid Build Coastguard Worker {
680*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *rtD3D = nullptr;
681*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getRenderTarget(context, imageIndex, samples, &rtD3D));
682*8975f5c5SAndroid Build Coastguard Worker *rtOut = static_cast<FramebufferAttachmentRenderTarget *>(rtD3D);
683*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
684*8975f5c5SAndroid Build Coastguard Worker }
685*8975f5c5SAndroid Build Coastguard Worker
setBaseLevel(const gl::Context * context,GLuint baseLevel)686*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::setBaseLevel(const gl::Context *context, GLuint baseLevel)
687*8975f5c5SAndroid Build Coastguard Worker {
688*8975f5c5SAndroid Build Coastguard Worker const int oldStorageWidth = std::max(1, getLevelZeroWidth());
689*8975f5c5SAndroid Build Coastguard Worker const int oldStorageHeight = std::max(1, getLevelZeroHeight());
690*8975f5c5SAndroid Build Coastguard Worker const int oldStorageDepth = std::max(1, getLevelZeroDepth());
691*8975f5c5SAndroid Build Coastguard Worker const int oldStorageFormat = getBaseLevelInternalFormat();
692*8975f5c5SAndroid Build Coastguard Worker mBaseLevel = baseLevel;
693*8975f5c5SAndroid Build Coastguard Worker
694*8975f5c5SAndroid Build Coastguard Worker // When the base level changes, the texture storage might not be valid anymore, since it could
695*8975f5c5SAndroid Build Coastguard Worker // have been created based on the dimensions of the previous specified level range.
696*8975f5c5SAndroid Build Coastguard Worker const int newStorageWidth = std::max(1, getLevelZeroWidth());
697*8975f5c5SAndroid Build Coastguard Worker const int newStorageHeight = std::max(1, getLevelZeroHeight());
698*8975f5c5SAndroid Build Coastguard Worker const int newStorageDepth = std::max(1, getLevelZeroDepth());
699*8975f5c5SAndroid Build Coastguard Worker const int newStorageFormat = getBaseLevelInternalFormat();
700*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage &&
701*8975f5c5SAndroid Build Coastguard Worker (newStorageWidth != oldStorageWidth || newStorageHeight != oldStorageHeight ||
702*8975f5c5SAndroid Build Coastguard Worker newStorageDepth != oldStorageDepth || newStorageFormat != oldStorageFormat))
703*8975f5c5SAndroid Build Coastguard Worker {
704*8975f5c5SAndroid Build Coastguard Worker markAllImagesDirty();
705*8975f5c5SAndroid Build Coastguard Worker
706*8975f5c5SAndroid Build Coastguard Worker // Iterate over all images, and backup the content if it's been used as a render target. The
707*8975f5c5SAndroid Build Coastguard Worker // D3D11 backend can automatically restore images on storage destroy, but it only works for
708*8975f5c5SAndroid Build Coastguard Worker // images that have been associated with the texture storage before, which is insufficient
709*8975f5c5SAndroid Build Coastguard Worker // here.
710*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage->isRenderTarget())
711*8975f5c5SAndroid Build Coastguard Worker {
712*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator iterator = imageIterator();
713*8975f5c5SAndroid Build Coastguard Worker while (iterator.hasNext())
714*8975f5c5SAndroid Build Coastguard Worker {
715*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex index = iterator.next();
716*8975f5c5SAndroid Build Coastguard Worker const GLsizei samples = getRenderToTextureSamples();
717*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *renderTarget = nullptr;
718*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexStorage->findRenderTarget(context, index, samples, &renderTarget));
719*8975f5c5SAndroid Build Coastguard Worker if (renderTarget)
720*8975f5c5SAndroid Build Coastguard Worker {
721*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImage(index)->copyFromTexStorage(context, index, mTexStorage));
722*8975f5c5SAndroid Build Coastguard Worker }
723*8975f5c5SAndroid Build Coastguard Worker }
724*8975f5c5SAndroid Build Coastguard Worker }
725*8975f5c5SAndroid Build Coastguard Worker
726*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
727*8975f5c5SAndroid Build Coastguard Worker }
728*8975f5c5SAndroid Build Coastguard Worker
729*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
730*8975f5c5SAndroid Build Coastguard Worker }
731*8975f5c5SAndroid Build Coastguard Worker
onLabelUpdate(const gl::Context * context)732*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::onLabelUpdate(const gl::Context *context)
733*8975f5c5SAndroid Build Coastguard Worker {
734*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
735*8975f5c5SAndroid Build Coastguard Worker {
736*8975f5c5SAndroid Build Coastguard Worker mTexStorage->setLabel(mState.getLabel());
737*8975f5c5SAndroid Build Coastguard Worker }
738*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
739*8975f5c5SAndroid Build Coastguard Worker }
740*8975f5c5SAndroid Build Coastguard Worker
syncState(const gl::Context * context,const gl::Texture::DirtyBits & dirtyBits,gl::Command source)741*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::syncState(const gl::Context *context,
742*8975f5c5SAndroid Build Coastguard Worker const gl::Texture::DirtyBits &dirtyBits,
743*8975f5c5SAndroid Build Coastguard Worker gl::Command source)
744*8975f5c5SAndroid Build Coastguard Worker {
745*8975f5c5SAndroid Build Coastguard Worker // This could be improved using dirty bits.
746*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
747*8975f5c5SAndroid Build Coastguard Worker }
748*8975f5c5SAndroid Build Coastguard Worker
releaseTexStorage(const gl::Context * context,const gl::TexLevelMask & copyStorageToImagesMask)749*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::releaseTexStorage(const gl::Context *context,
750*8975f5c5SAndroid Build Coastguard Worker const gl::TexLevelMask ©StorageToImagesMask)
751*8975f5c5SAndroid Build Coastguard Worker {
752*8975f5c5SAndroid Build Coastguard Worker if (!mTexStorage)
753*8975f5c5SAndroid Build Coastguard Worker {
754*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
755*8975f5c5SAndroid Build Coastguard Worker }
756*8975f5c5SAndroid Build Coastguard Worker
757*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage->isRenderTarget())
758*8975f5c5SAndroid Build Coastguard Worker {
759*8975f5c5SAndroid Build Coastguard Worker const GLenum storageFormat = getBaseLevelInternalFormat();
760*8975f5c5SAndroid Build Coastguard Worker const size_t storageLevels = mTexStorage->getLevelCount();
761*8975f5c5SAndroid Build Coastguard Worker
762*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator iterator = imageIterator();
763*8975f5c5SAndroid Build Coastguard Worker while (iterator.hasNext())
764*8975f5c5SAndroid Build Coastguard Worker {
765*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex index = iterator.next();
766*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
767*8975f5c5SAndroid Build Coastguard Worker const int storageWidth = std::max(1, getLevelZeroWidth() >> index.getLevelIndex());
768*8975f5c5SAndroid Build Coastguard Worker const int storageHeight = std::max(1, getLevelZeroHeight() >> index.getLevelIndex());
769*8975f5c5SAndroid Build Coastguard Worker if (image && isImageComplete(index) && image->getWidth() == storageWidth &&
770*8975f5c5SAndroid Build Coastguard Worker image->getHeight() == storageHeight &&
771*8975f5c5SAndroid Build Coastguard Worker image->getInternalFormat() == storageFormat &&
772*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex() < static_cast<int>(storageLevels) &&
773*8975f5c5SAndroid Build Coastguard Worker copyStorageToImagesMask[index.getLevelIndex()])
774*8975f5c5SAndroid Build Coastguard Worker {
775*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->copyFromTexStorage(context, index, mTexStorage));
776*8975f5c5SAndroid Build Coastguard Worker }
777*8975f5c5SAndroid Build Coastguard Worker }
778*8975f5c5SAndroid Build Coastguard Worker }
779*8975f5c5SAndroid Build Coastguard Worker
780*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::StorageReleased);
781*8975f5c5SAndroid Build Coastguard Worker
782*8975f5c5SAndroid Build Coastguard Worker auto err = mTexStorage->onDestroy(context);
783*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mTexStorage);
784*8975f5c5SAndroid Build Coastguard Worker return err;
785*8975f5c5SAndroid Build Coastguard Worker }
786*8975f5c5SAndroid Build Coastguard Worker
onDestroy(const gl::Context * context)787*8975f5c5SAndroid Build Coastguard Worker void TextureD3D::onDestroy(const gl::Context *context)
788*8975f5c5SAndroid Build Coastguard Worker {
789*8975f5c5SAndroid Build Coastguard Worker (void)releaseTexStorage(context, gl::TexLevelMask());
790*8975f5c5SAndroid Build Coastguard Worker }
791*8975f5c5SAndroid Build Coastguard Worker
initializeContents(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex)792*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D::initializeContents(const gl::Context *context,
793*8975f5c5SAndroid Build Coastguard Worker GLenum binding,
794*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &imageIndex)
795*8975f5c5SAndroid Build Coastguard Worker {
796*8975f5c5SAndroid Build Coastguard Worker ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
797*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex index = imageIndex;
798*8975f5c5SAndroid Build Coastguard Worker
799*8975f5c5SAndroid Build Coastguard Worker // Special case for D3D11 3D textures. We can't create render targets for individual layers of a
800*8975f5c5SAndroid Build Coastguard Worker // 3D texture, so force the clear to the entire mip. There shouldn't ever be a case where we
801*8975f5c5SAndroid Build Coastguard Worker // would lose existing data.
802*8975f5c5SAndroid Build Coastguard Worker if (index.getType() == gl::TextureType::_3D)
803*8975f5c5SAndroid Build Coastguard Worker {
804*8975f5c5SAndroid Build Coastguard Worker index = gl::ImageIndex::Make3D(index.getLevelIndex(), gl::ImageIndex::kEntireLevel);
805*8975f5c5SAndroid Build Coastguard Worker }
806*8975f5c5SAndroid Build Coastguard Worker else if (index.getType() == gl::TextureType::_2DArray && !index.hasLayer())
807*8975f5c5SAndroid Build Coastguard Worker {
808*8975f5c5SAndroid Build Coastguard Worker std::array<GLint, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> tempLayerCounts;
809*8975f5c5SAndroid Build Coastguard Worker
810*8975f5c5SAndroid Build Coastguard Worker GLint levelIndex = index.getLevelIndex();
811*8975f5c5SAndroid Build Coastguard Worker tempLayerCounts[levelIndex] = getLayerCount(levelIndex);
812*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator iterator =
813*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator::Make2DArray(levelIndex, levelIndex + 1, tempLayerCounts.data());
814*8975f5c5SAndroid Build Coastguard Worker while (iterator.hasNext())
815*8975f5c5SAndroid Build Coastguard Worker {
816*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeContents(context, GL_NONE, iterator.next()));
817*8975f5c5SAndroid Build Coastguard Worker }
818*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
819*8975f5c5SAndroid Build Coastguard Worker }
820*8975f5c5SAndroid Build Coastguard Worker else if (index.getType() == gl::TextureType::_2DMultisampleArray && !index.hasLayer())
821*8975f5c5SAndroid Build Coastguard Worker {
822*8975f5c5SAndroid Build Coastguard Worker std::array<GLint, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> tempLayerCounts;
823*8975f5c5SAndroid Build Coastguard Worker
824*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getLevelIndex() == 0);
825*8975f5c5SAndroid Build Coastguard Worker tempLayerCounts[0] = getLayerCount(0);
826*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator iterator =
827*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator::Make2DMultisampleArray(tempLayerCounts.data());
828*8975f5c5SAndroid Build Coastguard Worker while (iterator.hasNext())
829*8975f5c5SAndroid Build Coastguard Worker {
830*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeContents(context, GL_NONE, iterator.next()));
831*8975f5c5SAndroid Build Coastguard Worker }
832*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
833*8975f5c5SAndroid Build Coastguard Worker }
834*8975f5c5SAndroid Build Coastguard Worker
835*8975f5c5SAndroid Build Coastguard Worker // Force image clean.
836*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = getImage(index);
837*8975f5c5SAndroid Build Coastguard Worker if (image)
838*8975f5c5SAndroid Build Coastguard Worker {
839*8975f5c5SAndroid Build Coastguard Worker image->markClean();
840*8975f5c5SAndroid Build Coastguard Worker }
841*8975f5c5SAndroid Build Coastguard Worker
842*8975f5c5SAndroid Build Coastguard Worker // Fast path: can use a render target clear.
843*8975f5c5SAndroid Build Coastguard Worker // We don't use the fast path with the zero max lod workaround because it would introduce a race
844*8975f5c5SAndroid Build Coastguard Worker // between the rendertarget and the staging images.
845*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesD3D &features = mRenderer->getFeatures();
846*8975f5c5SAndroid Build Coastguard Worker bool shouldUseClear = (image == nullptr);
847*8975f5c5SAndroid Build Coastguard Worker if (canCreateRenderTargetForImage(index) && !features.zeroMaxLodWorkaround.enabled &&
848*8975f5c5SAndroid Build Coastguard Worker (shouldUseClear || features.allowClearForRobustResourceInit.enabled))
849*8975f5c5SAndroid Build Coastguard Worker {
850*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
851*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
852*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *renderTarget = nullptr;
853*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexStorage->getRenderTarget(context, index, 0, &renderTarget));
854*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->initRenderTarget(context, renderTarget));
855*8975f5c5SAndroid Build Coastguard Worker
856*8975f5c5SAndroid Build Coastguard Worker // Force image clean again, the texture storage may have been re-created and the image used.
857*8975f5c5SAndroid Build Coastguard Worker if (image)
858*8975f5c5SAndroid Build Coastguard Worker {
859*8975f5c5SAndroid Build Coastguard Worker image->markClean();
860*8975f5c5SAndroid Build Coastguard Worker }
861*8975f5c5SAndroid Build Coastguard Worker
862*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
863*8975f5c5SAndroid Build Coastguard Worker }
864*8975f5c5SAndroid Build Coastguard Worker
865*8975f5c5SAndroid Build Coastguard Worker ASSERT(image != nullptr);
866*8975f5c5SAndroid Build Coastguard Worker
867*8975f5c5SAndroid Build Coastguard Worker // Slow path: non-renderable texture or the texture levels aren't set up.
868*8975f5c5SAndroid Build Coastguard Worker const auto &formatInfo = gl::GetSizedInternalFormatInfo(image->getInternalFormat());
869*8975f5c5SAndroid Build Coastguard Worker
870*8975f5c5SAndroid Build Coastguard Worker GLuint imageBytes = 0;
871*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeRowPitch(formatInfo.type, image->getWidth(),
872*8975f5c5SAndroid Build Coastguard Worker 1, 0, &imageBytes));
873*8975f5c5SAndroid Build Coastguard Worker imageBytes *= image->getHeight() * image->getDepth();
874*8975f5c5SAndroid Build Coastguard Worker
875*8975f5c5SAndroid Build Coastguard Worker gl::PixelUnpackState zeroDataUnpackState;
876*8975f5c5SAndroid Build Coastguard Worker zeroDataUnpackState.alignment = 1;
877*8975f5c5SAndroid Build Coastguard Worker
878*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer *zeroBuffer = nullptr;
879*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_ALLOC(contextD3D, context->getZeroFilledBuffer(imageBytes, &zeroBuffer));
880*8975f5c5SAndroid Build Coastguard Worker
881*8975f5c5SAndroid Build Coastguard Worker if (shouldUseSetData(image))
882*8975f5c5SAndroid Build Coastguard Worker {
883*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexStorage->setData(context, index, image, nullptr, formatInfo.type,
884*8975f5c5SAndroid Build Coastguard Worker zeroDataUnpackState, zeroBuffer->data()));
885*8975f5c5SAndroid Build Coastguard Worker }
886*8975f5c5SAndroid Build Coastguard Worker else
887*8975f5c5SAndroid Build Coastguard Worker {
888*8975f5c5SAndroid Build Coastguard Worker gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
889*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(image->loadData(context, fullImageArea, zeroDataUnpackState, formatInfo.type,
890*8975f5c5SAndroid Build Coastguard Worker zeroBuffer->data(), false));
891*8975f5c5SAndroid Build Coastguard Worker
892*8975f5c5SAndroid Build Coastguard Worker // Force an update to the tex storage so we avoid problems with subImage and dirty regions.
893*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
894*8975f5c5SAndroid Build Coastguard Worker {
895*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, fullImageArea));
896*8975f5c5SAndroid Build Coastguard Worker image->markClean();
897*8975f5c5SAndroid Build Coastguard Worker }
898*8975f5c5SAndroid Build Coastguard Worker else
899*8975f5c5SAndroid Build Coastguard Worker {
900*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
901*8975f5c5SAndroid Build Coastguard Worker }
902*8975f5c5SAndroid Build Coastguard Worker }
903*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
904*8975f5c5SAndroid Build Coastguard Worker }
905*8975f5c5SAndroid Build Coastguard Worker
getRenderToTextureSamples()906*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D::getRenderToTextureSamples()
907*8975f5c5SAndroid Build Coastguard Worker {
908*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
909*8975f5c5SAndroid Build Coastguard Worker {
910*8975f5c5SAndroid Build Coastguard Worker return mTexStorage->getRenderToTextureSamples();
911*8975f5c5SAndroid Build Coastguard Worker }
912*8975f5c5SAndroid Build Coastguard Worker return 0;
913*8975f5c5SAndroid Build Coastguard Worker }
914*8975f5c5SAndroid Build Coastguard Worker
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)915*8975f5c5SAndroid Build Coastguard Worker void TextureD3D::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
916*8975f5c5SAndroid Build Coastguard Worker {
917*8975f5c5SAndroid Build Coastguard Worker onStateChange(message);
918*8975f5c5SAndroid Build Coastguard Worker }
919*8975f5c5SAndroid Build Coastguard Worker
TextureD3D_2D(const gl::TextureState & state,RendererD3D * renderer)920*8975f5c5SAndroid Build Coastguard Worker TextureD3D_2D::TextureD3D_2D(const gl::TextureState &state, RendererD3D *renderer)
921*8975f5c5SAndroid Build Coastguard Worker : TextureD3D(state, renderer)
922*8975f5c5SAndroid Build Coastguard Worker {
923*8975f5c5SAndroid Build Coastguard Worker mEGLImageTarget = false;
924*8975f5c5SAndroid Build Coastguard Worker for (auto &image : mImageArray)
925*8975f5c5SAndroid Build Coastguard Worker {
926*8975f5c5SAndroid Build Coastguard Worker image.reset(renderer->createImage());
927*8975f5c5SAndroid Build Coastguard Worker }
928*8975f5c5SAndroid Build Coastguard Worker }
929*8975f5c5SAndroid Build Coastguard Worker
onDestroy(const gl::Context * context)930*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_2D::onDestroy(const gl::Context *context)
931*8975f5c5SAndroid Build Coastguard Worker {
932*8975f5c5SAndroid Build Coastguard Worker // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage
933*8975f5c5SAndroid Build Coastguard Worker // for some of their data. If TextureStorage is deleted before the Images, then their data will
934*8975f5c5SAndroid Build Coastguard Worker // be wastefully copied back from the GPU before we delete the Images.
935*8975f5c5SAndroid Build Coastguard Worker for (auto &image : mImageArray)
936*8975f5c5SAndroid Build Coastguard Worker {
937*8975f5c5SAndroid Build Coastguard Worker image.reset();
938*8975f5c5SAndroid Build Coastguard Worker }
939*8975f5c5SAndroid Build Coastguard Worker return TextureD3D::onDestroy(context);
940*8975f5c5SAndroid Build Coastguard Worker }
941*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D_2D()942*8975f5c5SAndroid Build Coastguard Worker TextureD3D_2D::~TextureD3D_2D() {}
943*8975f5c5SAndroid Build Coastguard Worker
getImage(int level,int layer) const944*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_2D::getImage(int level, int layer) const
945*8975f5c5SAndroid Build Coastguard Worker {
946*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
947*8975f5c5SAndroid Build Coastguard Worker ASSERT(layer == 0);
948*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level].get();
949*8975f5c5SAndroid Build Coastguard Worker }
950*8975f5c5SAndroid Build Coastguard Worker
getImage(const gl::ImageIndex & index) const951*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_2D::getImage(const gl::ImageIndex &index) const
952*8975f5c5SAndroid Build Coastguard Worker {
953*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
954*8975f5c5SAndroid Build Coastguard Worker ASSERT(!index.hasLayer());
955*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getType() == gl::TextureType::_2D ||
956*8975f5c5SAndroid Build Coastguard Worker index.getType() == gl::TextureType::VideoImage);
957*8975f5c5SAndroid Build Coastguard Worker return mImageArray[index.getLevelIndex()].get();
958*8975f5c5SAndroid Build Coastguard Worker }
959*8975f5c5SAndroid Build Coastguard Worker
getLayerCount(int level) const960*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_2D::getLayerCount(int level) const
961*8975f5c5SAndroid Build Coastguard Worker {
962*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
963*8975f5c5SAndroid Build Coastguard Worker return 1;
964*8975f5c5SAndroid Build Coastguard Worker }
965*8975f5c5SAndroid Build Coastguard Worker
getWidth(GLint level) const966*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_2D::getWidth(GLint level) const
967*8975f5c5SAndroid Build Coastguard Worker {
968*8975f5c5SAndroid Build Coastguard Worker if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
969*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level]->getWidth();
970*8975f5c5SAndroid Build Coastguard Worker else
971*8975f5c5SAndroid Build Coastguard Worker return 0;
972*8975f5c5SAndroid Build Coastguard Worker }
973*8975f5c5SAndroid Build Coastguard Worker
getHeight(GLint level) const974*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_2D::getHeight(GLint level) const
975*8975f5c5SAndroid Build Coastguard Worker {
976*8975f5c5SAndroid Build Coastguard Worker if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
977*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level]->getHeight();
978*8975f5c5SAndroid Build Coastguard Worker else
979*8975f5c5SAndroid Build Coastguard Worker return 0;
980*8975f5c5SAndroid Build Coastguard Worker }
981*8975f5c5SAndroid Build Coastguard Worker
getInternalFormat(GLint level) const982*8975f5c5SAndroid Build Coastguard Worker GLenum TextureD3D_2D::getInternalFormat(GLint level) const
983*8975f5c5SAndroid Build Coastguard Worker {
984*8975f5c5SAndroid Build Coastguard Worker if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
985*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level]->getInternalFormat();
986*8975f5c5SAndroid Build Coastguard Worker else
987*8975f5c5SAndroid Build Coastguard Worker return GL_NONE;
988*8975f5c5SAndroid Build Coastguard Worker }
989*8975f5c5SAndroid Build Coastguard Worker
isDepth(GLint level) const990*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2D::isDepth(GLint level) const
991*8975f5c5SAndroid Build Coastguard Worker {
992*8975f5c5SAndroid Build Coastguard Worker return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
993*8975f5c5SAndroid Build Coastguard Worker }
994*8975f5c5SAndroid Build Coastguard Worker
isSRGB(GLint level) const995*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2D::isSRGB(GLint level) const
996*8975f5c5SAndroid Build Coastguard Worker {
997*8975f5c5SAndroid Build Coastguard Worker return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB;
998*8975f5c5SAndroid Build Coastguard Worker }
999*8975f5c5SAndroid Build Coastguard Worker
setImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)1000*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::setImage(const gl::Context *context,
1001*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1002*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1003*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
1004*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1005*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1006*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
1007*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
1008*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1009*8975f5c5SAndroid Build Coastguard Worker {
1010*8975f5c5SAndroid Build Coastguard Worker ASSERT((index.getTarget() == gl::TextureTarget::_2D ||
1011*8975f5c5SAndroid Build Coastguard Worker index.getTarget() == gl::TextureTarget::VideoImage) &&
1012*8975f5c5SAndroid Build Coastguard Worker size.depth == 1);
1013*8975f5c5SAndroid Build Coastguard Worker
1014*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
1015*8975f5c5SAndroid Build Coastguard Worker
1016*8975f5c5SAndroid Build Coastguard Worker bool fastUnpacked = false;
1017*8975f5c5SAndroid Build Coastguard Worker
1018*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
1019*8975f5c5SAndroid Build Coastguard Worker size, false));
1020*8975f5c5SAndroid Build Coastguard Worker
1021*8975f5c5SAndroid Build Coastguard Worker // Attempt a fast gpu copy of the pixel data to the surface
1022*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
1023*8975f5c5SAndroid Build Coastguard Worker {
1024*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexStorage->releaseMultisampledTexStorageForLevel(index.getLevelIndex()));
1025*8975f5c5SAndroid Build Coastguard Worker }
1026*8975f5c5SAndroid Build Coastguard Worker if (isFastUnpackable(unpackBuffer, unpack, internalFormatInfo.sizedInternalFormat) &&
1027*8975f5c5SAndroid Build Coastguard Worker isLevelComplete(index.getLevelIndex()))
1028*8975f5c5SAndroid Build Coastguard Worker {
1029*8975f5c5SAndroid Build Coastguard Worker // Will try to create RT storage if it does not exist
1030*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *destRenderTarget = nullptr;
1031*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget));
1032*8975f5c5SAndroid Build Coastguard Worker
1033*8975f5c5SAndroid Build Coastguard Worker gl::Box destArea(0, 0, 0, getWidth(index.getLevelIndex()), getHeight(index.getLevelIndex()),
1034*8975f5c5SAndroid Build Coastguard Worker 1);
1035*8975f5c5SAndroid Build Coastguard Worker
1036*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(fastUnpackPixels(context, unpack, unpackBuffer, pixels, destArea,
1037*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.sizedInternalFormat, type, destRenderTarget));
1038*8975f5c5SAndroid Build Coastguard Worker
1039*8975f5c5SAndroid Build Coastguard Worker // Ensure we don't overwrite our newly initialized data
1040*8975f5c5SAndroid Build Coastguard Worker mImageArray[index.getLevelIndex()]->markClean();
1041*8975f5c5SAndroid Build Coastguard Worker
1042*8975f5c5SAndroid Build Coastguard Worker fastUnpacked = true;
1043*8975f5c5SAndroid Build Coastguard Worker }
1044*8975f5c5SAndroid Build Coastguard Worker
1045*8975f5c5SAndroid Build Coastguard Worker if (!fastUnpacked)
1046*8975f5c5SAndroid Build Coastguard Worker {
1047*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0));
1048*8975f5c5SAndroid Build Coastguard Worker }
1049*8975f5c5SAndroid Build Coastguard Worker
1050*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1051*8975f5c5SAndroid Build Coastguard Worker }
1052*8975f5c5SAndroid Build Coastguard Worker
setSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)1053*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::setSubImage(const gl::Context *context,
1054*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1055*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
1056*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1057*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1058*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
1059*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
1060*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1061*8975f5c5SAndroid Build Coastguard Worker {
1062*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0);
1063*8975f5c5SAndroid Build Coastguard Worker
1064*8975f5c5SAndroid Build Coastguard Worker GLenum mipFormat = getInternalFormat(index.getLevelIndex());
1065*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
1066*8975f5c5SAndroid Build Coastguard Worker {
1067*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexStorage->releaseMultisampledTexStorageForLevel(index.getLevelIndex()));
1068*8975f5c5SAndroid Build Coastguard Worker }
1069*8975f5c5SAndroid Build Coastguard Worker if (isFastUnpackable(unpackBuffer, unpack, mipFormat) && isLevelComplete(index.getLevelIndex()))
1070*8975f5c5SAndroid Build Coastguard Worker {
1071*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *renderTarget = nullptr;
1072*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &renderTarget));
1073*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mImageArray[index.getLevelIndex()]->isDirty());
1074*8975f5c5SAndroid Build Coastguard Worker
1075*8975f5c5SAndroid Build Coastguard Worker return fastUnpackPixels(context, unpack, unpackBuffer, pixels, area, mipFormat, type,
1076*8975f5c5SAndroid Build Coastguard Worker renderTarget);
1077*8975f5c5SAndroid Build Coastguard Worker }
1078*8975f5c5SAndroid Build Coastguard Worker else
1079*8975f5c5SAndroid Build Coastguard Worker {
1080*8975f5c5SAndroid Build Coastguard Worker return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer,
1081*8975f5c5SAndroid Build Coastguard Worker pixels, 0);
1082*8975f5c5SAndroid Build Coastguard Worker }
1083*8975f5c5SAndroid Build Coastguard Worker }
1084*8975f5c5SAndroid Build Coastguard Worker
setCompressedImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)1085*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::setCompressedImage(const gl::Context *context,
1086*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1087*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1088*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
1089*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
1090*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
1091*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1092*8975f5c5SAndroid Build Coastguard Worker {
1093*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2D && size.depth == 1);
1094*8975f5c5SAndroid Build Coastguard Worker
1095*8975f5c5SAndroid Build Coastguard Worker // compressed formats don't have separate sized internal formats-- we can just use the
1096*8975f5c5SAndroid Build Coastguard Worker // compressed format directly
1097*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false));
1098*8975f5c5SAndroid Build Coastguard Worker
1099*8975f5c5SAndroid Build Coastguard Worker return setCompressedImageImpl(context, index, unpack, pixels, 0);
1100*8975f5c5SAndroid Build Coastguard Worker }
1101*8975f5c5SAndroid Build Coastguard Worker
setCompressedSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)1102*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::setCompressedSubImage(const gl::Context *context,
1103*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1104*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
1105*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1106*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
1107*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
1108*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1109*8975f5c5SAndroid Build Coastguard Worker {
1110*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0);
1111*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
1112*8975f5c5SAndroid Build Coastguard Worker
1113*8975f5c5SAndroid Build Coastguard Worker return commitRegion(context, index, area);
1114*8975f5c5SAndroid Build Coastguard Worker }
1115*8975f5c5SAndroid Build Coastguard Worker
copyImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Rectangle & sourceArea,GLenum internalFormat,gl::Framebuffer * source)1116*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::copyImage(const gl::Context *context,
1117*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1118*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
1119*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1120*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
1121*8975f5c5SAndroid Build Coastguard Worker {
1122*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2D);
1123*8975f5c5SAndroid Build Coastguard Worker
1124*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
1125*8975f5c5SAndroid Build Coastguard Worker gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
1126*8975f5c5SAndroid Build Coastguard Worker gl::Extents sourceExtents(sourceArea.width, sourceArea.height, 1);
1127*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
1128*8975f5c5SAndroid Build Coastguard Worker sourceExtents, false));
1129*8975f5c5SAndroid Build Coastguard Worker
1130*8975f5c5SAndroid Build Coastguard Worker gl::Extents fbSize = source->getReadColorAttachment()->getSize();
1131*8975f5c5SAndroid Build Coastguard Worker
1132*8975f5c5SAndroid Build Coastguard Worker // Does the read area extend beyond the framebuffer?
1133*8975f5c5SAndroid Build Coastguard Worker bool outside = sourceArea.x < 0 || sourceArea.y < 0 ||
1134*8975f5c5SAndroid Build Coastguard Worker sourceArea.x + sourceArea.width > fbSize.width ||
1135*8975f5c5SAndroid Build Coastguard Worker sourceArea.y + sourceArea.height > fbSize.height;
1136*8975f5c5SAndroid Build Coastguard Worker
1137*8975f5c5SAndroid Build Coastguard Worker // WebGL requires that pixels that would be outside the framebuffer are treated as zero values,
1138*8975f5c5SAndroid Build Coastguard Worker // so clear the mip level to 0 prior to making the copy if any pixel would be sampled outside.
1139*8975f5c5SAndroid Build Coastguard Worker // Same thing for robust resource init.
1140*8975f5c5SAndroid Build Coastguard Worker if (outside && (context->isWebGL() || context->isRobustResourceInitEnabled()))
1141*8975f5c5SAndroid Build Coastguard Worker {
1142*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeContents(context, GL_NONE, index));
1143*8975f5c5SAndroid Build Coastguard Worker }
1144*8975f5c5SAndroid Build Coastguard Worker
1145*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedArea;
1146*8975f5c5SAndroid Build Coastguard Worker if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
1147*8975f5c5SAndroid Build Coastguard Worker {
1148*8975f5c5SAndroid Build Coastguard Worker // Empty source area, nothing to do.
1149*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1150*8975f5c5SAndroid Build Coastguard Worker }
1151*8975f5c5SAndroid Build Coastguard Worker
1152*8975f5c5SAndroid Build Coastguard Worker gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0);
1153*8975f5c5SAndroid Build Coastguard Worker
1154*8975f5c5SAndroid Build Coastguard Worker // If the zero max LOD workaround is active, then we can't sample from individual layers of the
1155*8975f5c5SAndroid Build Coastguard Worker // framebuffer in shaders, so we should use the non-rendering copy path.
1156*8975f5c5SAndroid Build Coastguard Worker if (!canCreateRenderTargetForImage(index) ||
1157*8975f5c5SAndroid Build Coastguard Worker mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
1158*8975f5c5SAndroid Build Coastguard Worker {
1159*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, destOffset,
1160*8975f5c5SAndroid Build Coastguard Worker clippedArea, source));
1161*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
1162*8975f5c5SAndroid Build Coastguard Worker }
1163*8975f5c5SAndroid Build Coastguard Worker else
1164*8975f5c5SAndroid Build Coastguard Worker {
1165*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
1166*8975f5c5SAndroid Build Coastguard Worker
1167*8975f5c5SAndroid Build Coastguard Worker if (clippedArea.width != 0 && clippedArea.height != 0 &&
1168*8975f5c5SAndroid Build Coastguard Worker isValidLevel(index.getLevelIndex()))
1169*8975f5c5SAndroid Build Coastguard Worker {
1170*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
1171*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage2D(context, source, clippedArea,
1172*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.format, destOffset, mTexStorage,
1173*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex()));
1174*8975f5c5SAndroid Build Coastguard Worker }
1175*8975f5c5SAndroid Build Coastguard Worker }
1176*8975f5c5SAndroid Build Coastguard Worker
1177*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1178*8975f5c5SAndroid Build Coastguard Worker }
1179*8975f5c5SAndroid Build Coastguard Worker
copySubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,const gl::Rectangle & sourceArea,gl::Framebuffer * source)1180*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::copySubImage(const gl::Context *context,
1181*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1182*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
1183*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
1184*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
1185*8975f5c5SAndroid Build Coastguard Worker {
1186*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2D && destOffset.z == 0);
1187*8975f5c5SAndroid Build Coastguard Worker
1188*8975f5c5SAndroid Build Coastguard Worker gl::Extents fbSize = source->getReadColorAttachment()->getSize();
1189*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedArea;
1190*8975f5c5SAndroid Build Coastguard Worker if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
1191*8975f5c5SAndroid Build Coastguard Worker {
1192*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1193*8975f5c5SAndroid Build Coastguard Worker }
1194*8975f5c5SAndroid Build Coastguard Worker const gl::Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x,
1195*8975f5c5SAndroid Build Coastguard Worker destOffset.y + clippedArea.y - sourceArea.y, 0);
1196*8975f5c5SAndroid Build Coastguard Worker
1197*8975f5c5SAndroid Build Coastguard Worker // can only make our texture storage to a render target if level 0 is defined (with a width &
1198*8975f5c5SAndroid Build Coastguard Worker // height) and the current level we're copying to is defined (with appropriate format, width &
1199*8975f5c5SAndroid Build Coastguard Worker // height)
1200*8975f5c5SAndroid Build Coastguard Worker
1201*8975f5c5SAndroid Build Coastguard Worker // If the zero max LOD workaround is active, then we can't sample from individual layers of the
1202*8975f5c5SAndroid Build Coastguard Worker // framebuffer in shaders, so we should use the non-rendering copy path.
1203*8975f5c5SAndroid Build Coastguard Worker if (!canCreateRenderTargetForImage(index) ||
1204*8975f5c5SAndroid Build Coastguard Worker mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
1205*8975f5c5SAndroid Build Coastguard Worker {
1206*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, clippedOffset,
1207*8975f5c5SAndroid Build Coastguard Worker clippedArea, source));
1208*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
1209*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1210*8975f5c5SAndroid Build Coastguard Worker }
1211*8975f5c5SAndroid Build Coastguard Worker else
1212*8975f5c5SAndroid Build Coastguard Worker {
1213*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
1214*8975f5c5SAndroid Build Coastguard Worker
1215*8975f5c5SAndroid Build Coastguard Worker if (isValidLevel(index.getLevelIndex()))
1216*8975f5c5SAndroid Build Coastguard Worker {
1217*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
1218*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage2D(context, source, clippedArea,
1219*8975f5c5SAndroid Build Coastguard Worker gl::GetUnsizedFormat(getBaseLevelInternalFormat()),
1220*8975f5c5SAndroid Build Coastguard Worker clippedOffset, mTexStorage, index.getLevelIndex()));
1221*8975f5c5SAndroid Build Coastguard Worker }
1222*8975f5c5SAndroid Build Coastguard Worker }
1223*8975f5c5SAndroid Build Coastguard Worker
1224*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1225*8975f5c5SAndroid Build Coastguard Worker }
1226*8975f5c5SAndroid Build Coastguard Worker
copyTexture(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,GLenum type,GLint sourceLevel,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)1227*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::copyTexture(const gl::Context *context,
1228*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1229*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1230*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1231*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
1232*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
1233*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
1234*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
1235*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
1236*8975f5c5SAndroid Build Coastguard Worker {
1237*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2D);
1238*8975f5c5SAndroid Build Coastguard Worker
1239*8975f5c5SAndroid Build Coastguard Worker gl::TextureType sourceType = source->getType();
1240*8975f5c5SAndroid Build Coastguard Worker
1241*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
1242*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(
1243*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
1244*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
1245*8975f5c5SAndroid Build Coastguard Worker 1);
1246*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
1247*8975f5c5SAndroid Build Coastguard Worker size, false));
1248*8975f5c5SAndroid Build Coastguard Worker
1249*8975f5c5SAndroid Build Coastguard Worker gl::Box sourceBox(0, 0, 0, size.width, size.height, 1);
1250*8975f5c5SAndroid Build Coastguard Worker gl::Offset destOffset(0, 0, 0);
1251*8975f5c5SAndroid Build Coastguard Worker
1252*8975f5c5SAndroid Build Coastguard Worker if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(index))
1253*8975f5c5SAndroid Build Coastguard Worker {
1254*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
1255*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidLevel(index.getLevelIndex()));
1256*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
1257*8975f5c5SAndroid Build Coastguard Worker
1258*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D,
1259*8975f5c5SAndroid Build Coastguard Worker sourceBox, internalFormatInfo.format,
1260*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type, destOffset, mTexStorage,
1261*8975f5c5SAndroid Build Coastguard Worker index.getTarget(), index.getLevelIndex(), unpackFlipY,
1262*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
1263*8975f5c5SAndroid Build Coastguard Worker }
1264*8975f5c5SAndroid Build Coastguard Worker else
1265*8975f5c5SAndroid Build Coastguard Worker {
1266*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel);
1267*8975f5c5SAndroid Build Coastguard Worker TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
1268*8975f5c5SAndroid Build Coastguard Worker ImageD3D *sourceImage = nullptr;
1269*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
1270*8975f5c5SAndroid Build Coastguard Worker
1271*8975f5c5SAndroid Build Coastguard Worker ImageD3D *destImage = nullptr;
1272*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
1273*8975f5c5SAndroid Build Coastguard Worker
1274*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
1275*8975f5c5SAndroid Build Coastguard Worker unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
1276*8975f5c5SAndroid Build Coastguard Worker
1277*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
1278*8975f5c5SAndroid Build Coastguard Worker
1279*8975f5c5SAndroid Build Coastguard Worker gl::Box destRegion(destOffset, size);
1280*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, destRegion));
1281*8975f5c5SAndroid Build Coastguard Worker }
1282*8975f5c5SAndroid Build Coastguard Worker
1283*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1284*8975f5c5SAndroid Build Coastguard Worker }
1285*8975f5c5SAndroid Build Coastguard Worker
copySubTexture(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,GLint sourceLevel,const gl::Box & sourceBox,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)1286*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::copySubTexture(const gl::Context *context,
1287*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1288*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
1289*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
1290*8975f5c5SAndroid Build Coastguard Worker const gl::Box &sourceBox,
1291*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
1292*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
1293*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
1294*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
1295*8975f5c5SAndroid Build Coastguard Worker {
1296*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2D);
1297*8975f5c5SAndroid Build Coastguard Worker
1298*8975f5c5SAndroid Build Coastguard Worker if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(index))
1299*8975f5c5SAndroid Build Coastguard Worker {
1300*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
1301*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidLevel(index.getLevelIndex()));
1302*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
1303*8975f5c5SAndroid Build Coastguard Worker
1304*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
1305*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex()));
1306*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D,
1307*8975f5c5SAndroid Build Coastguard Worker sourceBox, internalFormatInfo.format,
1308*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type, destOffset, mTexStorage,
1309*8975f5c5SAndroid Build Coastguard Worker index.getTarget(), index.getLevelIndex(), unpackFlipY,
1310*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
1311*8975f5c5SAndroid Build Coastguard Worker }
1312*8975f5c5SAndroid Build Coastguard Worker else
1313*8975f5c5SAndroid Build Coastguard Worker {
1314*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel);
1315*8975f5c5SAndroid Build Coastguard Worker TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
1316*8975f5c5SAndroid Build Coastguard Worker ImageD3D *sourceImage = nullptr;
1317*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
1318*8975f5c5SAndroid Build Coastguard Worker
1319*8975f5c5SAndroid Build Coastguard Worker ImageD3D *destImage = nullptr;
1320*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
1321*8975f5c5SAndroid Build Coastguard Worker
1322*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
1323*8975f5c5SAndroid Build Coastguard Worker unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
1324*8975f5c5SAndroid Build Coastguard Worker
1325*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
1326*8975f5c5SAndroid Build Coastguard Worker
1327*8975f5c5SAndroid Build Coastguard Worker gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceBox.width, sourceBox.height, 1);
1328*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, destRegion));
1329*8975f5c5SAndroid Build Coastguard Worker }
1330*8975f5c5SAndroid Build Coastguard Worker
1331*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1332*8975f5c5SAndroid Build Coastguard Worker }
1333*8975f5c5SAndroid Build Coastguard Worker
copyCompressedTexture(const gl::Context * context,const gl::Texture * source)1334*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::copyCompressedTexture(const gl::Context *context,
1335*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
1336*8975f5c5SAndroid Build Coastguard Worker {
1337*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget sourceTarget = NonCubeTextureTypeToTarget(source->getType());
1338*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel = 0;
1339*8975f5c5SAndroid Build Coastguard Worker
1340*8975f5c5SAndroid Build Coastguard Worker GLint destLevel = 0;
1341*8975f5c5SAndroid Build Coastguard Worker
1342*8975f5c5SAndroid Build Coastguard Worker GLenum sizedInternalFormat =
1343*8975f5c5SAndroid Build Coastguard Worker source->getFormat(sourceTarget, sourceLevel).info->sizedInternalFormat;
1344*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)),
1345*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1);
1346*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, destLevel, sizedInternalFormat, size, false));
1347*8975f5c5SAndroid Build Coastguard Worker
1348*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeStorage(context, BindFlags()));
1349*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
1350*8975f5c5SAndroid Build Coastguard Worker
1351*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
1352*8975f5c5SAndroid Build Coastguard Worker mRenderer->copyCompressedTexture(context, source, sourceLevel, mTexStorage, destLevel));
1353*8975f5c5SAndroid Build Coastguard Worker
1354*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1355*8975f5c5SAndroid Build Coastguard Worker }
1356*8975f5c5SAndroid Build Coastguard Worker
setStorage(const gl::Context * context,gl::TextureType type,size_t levels,GLenum internalFormat,const gl::Extents & size)1357*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::setStorage(const gl::Context *context,
1358*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
1359*8975f5c5SAndroid Build Coastguard Worker size_t levels,
1360*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1361*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size)
1362*8975f5c5SAndroid Build Coastguard Worker {
1363*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == gl::TextureType::_2D && size.depth == 1);
1364*8975f5c5SAndroid Build Coastguard Worker
1365*8975f5c5SAndroid Build Coastguard Worker for (size_t level = 0; level < levels; level++)
1366*8975f5c5SAndroid Build Coastguard Worker {
1367*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelSize(std::max(1, size.width >> level), std::max(1, size.height >> level),
1368*8975f5c5SAndroid Build Coastguard Worker 1);
1369*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, level, internalFormat, levelSize, true));
1370*8975f5c5SAndroid Build Coastguard Worker }
1371*8975f5c5SAndroid Build Coastguard Worker
1372*8975f5c5SAndroid Build Coastguard Worker for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1373*8975f5c5SAndroid Build Coastguard Worker {
1374*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, level, GL_NONE, gl::Extents(0, 0, 1), true));
1375*8975f5c5SAndroid Build Coastguard Worker }
1376*8975f5c5SAndroid Build Coastguard Worker
1377*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Verify storage creation had no errors
1378*8975f5c5SAndroid Build Coastguard Worker BindFlags flags;
1379*8975f5c5SAndroid Build Coastguard Worker flags.renderTarget = IsRenderTargetUsage(mState.getUsage());
1380*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage = {
1381*8975f5c5SAndroid Build Coastguard Worker mRenderer->createTextureStorage2D(internalFormat, flags, size.width, size.height,
1382*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(levels), mState.getLabel(), false),
1383*8975f5c5SAndroid Build Coastguard Worker context};
1384*8975f5c5SAndroid Build Coastguard Worker
1385*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
1386*8975f5c5SAndroid Build Coastguard Worker storage.release();
1387*8975f5c5SAndroid Build Coastguard Worker
1388*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
1389*8975f5c5SAndroid Build Coastguard Worker
1390*8975f5c5SAndroid Build Coastguard Worker mImmutable = true;
1391*8975f5c5SAndroid Build Coastguard Worker
1392*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1393*8975f5c5SAndroid Build Coastguard Worker }
1394*8975f5c5SAndroid Build Coastguard Worker
bindTexImage(const gl::Context * context,egl::Surface * surface)1395*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::bindTexImage(const gl::Context *context, egl::Surface *surface)
1396*8975f5c5SAndroid Build Coastguard Worker {
1397*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat = surface->getConfig()->renderTargetFormat;
1398*8975f5c5SAndroid Build Coastguard Worker
1399*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(surface->getWidth(), surface->getHeight(), 1);
1400*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, 0, internalformat, size, true));
1401*8975f5c5SAndroid Build Coastguard Worker
1402*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
1403*8975f5c5SAndroid Build Coastguard Worker
1404*8975f5c5SAndroid Build Coastguard Worker SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
1405*8975f5c5SAndroid Build Coastguard Worker ASSERT(surfaceD3D);
1406*8975f5c5SAndroid Build Coastguard Worker
1407*8975f5c5SAndroid Build Coastguard Worker mTexStorage = mRenderer->createTextureStorage2D(surfaceD3D->getSwapChain(), mState.getLabel());
1408*8975f5c5SAndroid Build Coastguard Worker mEGLImageTarget = false;
1409*8975f5c5SAndroid Build Coastguard Worker
1410*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = false;
1411*8975f5c5SAndroid Build Coastguard Worker mImageArray[0]->markClean();
1412*8975f5c5SAndroid Build Coastguard Worker
1413*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1414*8975f5c5SAndroid Build Coastguard Worker }
1415*8975f5c5SAndroid Build Coastguard Worker
releaseTexImage(const gl::Context * context)1416*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::releaseTexImage(const gl::Context *context)
1417*8975f5c5SAndroid Build Coastguard Worker {
1418*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
1419*8975f5c5SAndroid Build Coastguard Worker {
1420*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
1421*8975f5c5SAndroid Build Coastguard Worker }
1422*8975f5c5SAndroid Build Coastguard Worker
1423*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1424*8975f5c5SAndroid Build Coastguard Worker {
1425*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, i, GL_NONE, gl::Extents(0, 0, 1), true));
1426*8975f5c5SAndroid Build Coastguard Worker }
1427*8975f5c5SAndroid Build Coastguard Worker
1428*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1429*8975f5c5SAndroid Build Coastguard Worker }
1430*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)1431*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::setEGLImageTarget(const gl::Context *context,
1432*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
1433*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
1434*8975f5c5SAndroid Build Coastguard Worker {
1435*8975f5c5SAndroid Build Coastguard Worker EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image);
1436*8975f5c5SAndroid Build Coastguard Worker
1437*8975f5c5SAndroid Build Coastguard Worker // Set the properties of the base mip level from the EGL image
1438*8975f5c5SAndroid Build Coastguard Worker const auto &format = image->getFormat();
1439*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(static_cast<int>(image->getWidth()), static_cast<int>(image->getHeight()), 1);
1440*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, 0, format.info->sizedInternalFormat, size, true));
1441*8975f5c5SAndroid Build Coastguard Worker
1442*8975f5c5SAndroid Build Coastguard Worker // Clear all other images.
1443*8975f5c5SAndroid Build Coastguard Worker for (size_t level = 1; level < mImageArray.size(); level++)
1444*8975f5c5SAndroid Build Coastguard Worker {
1445*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, level, GL_NONE, gl::Extents(0, 0, 1), true));
1446*8975f5c5SAndroid Build Coastguard Worker }
1447*8975f5c5SAndroid Build Coastguard Worker
1448*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
1449*8975f5c5SAndroid Build Coastguard Worker mImageArray[0]->markClean();
1450*8975f5c5SAndroid Build Coastguard Worker
1451*8975f5c5SAndroid Build Coastguard Worker // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error.
1452*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *renderTargetD3D = nullptr;
1453*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D));
1454*8975f5c5SAndroid Build Coastguard Worker
1455*8975f5c5SAndroid Build Coastguard Worker mTexStorage =
1456*8975f5c5SAndroid Build Coastguard Worker mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D, mState.getLabel());
1457*8975f5c5SAndroid Build Coastguard Worker mEGLImageTarget = true;
1458*8975f5c5SAndroid Build Coastguard Worker
1459*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1460*8975f5c5SAndroid Build Coastguard Worker }
1461*8975f5c5SAndroid Build Coastguard Worker
initMipmapImages(const gl::Context * context)1462*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::initMipmapImages(const gl::Context *context)
1463*8975f5c5SAndroid Build Coastguard Worker {
1464*8975f5c5SAndroid Build Coastguard Worker const GLuint baseLevel = mState.getEffectiveBaseLevel();
1465*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = mState.getMipmapMaxLevel();
1466*8975f5c5SAndroid Build Coastguard Worker // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap
1467*8975f5c5SAndroid Build Coastguard Worker // levels.
1468*8975f5c5SAndroid Build Coastguard Worker for (GLuint level = baseLevel + 1; level <= maxLevel; level++)
1469*8975f5c5SAndroid Build Coastguard Worker {
1470*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelSize(std::max(getLevelZeroWidth() >> level, 1),
1471*8975f5c5SAndroid Build Coastguard Worker std::max(getLevelZeroHeight() >> level, 1), 1);
1472*8975f5c5SAndroid Build Coastguard Worker
1473*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, level, getBaseLevelInternalFormat(), levelSize, false));
1474*8975f5c5SAndroid Build Coastguard Worker }
1475*8975f5c5SAndroid Build Coastguard Worker
1476*8975f5c5SAndroid Build Coastguard Worker // We should be mip-complete now so generate the storage.
1477*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget()));
1478*8975f5c5SAndroid Build Coastguard Worker
1479*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1480*8975f5c5SAndroid Build Coastguard Worker }
1481*8975f5c5SAndroid Build Coastguard Worker
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)1482*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::getRenderTarget(const gl::Context *context,
1483*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1484*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
1485*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D **outRT)
1486*8975f5c5SAndroid Build Coastguard Worker {
1487*8975f5c5SAndroid Build Coastguard Worker ASSERT(!index.hasLayer());
1488*8975f5c5SAndroid Build Coastguard Worker
1489*8975f5c5SAndroid Build Coastguard Worker // ensure the underlying texture is created
1490*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
1491*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
1492*8975f5c5SAndroid Build Coastguard Worker
1493*8975f5c5SAndroid Build Coastguard Worker return mTexStorage->getRenderTarget(context, index, samples, outRT);
1494*8975f5c5SAndroid Build Coastguard Worker }
1495*8975f5c5SAndroid Build Coastguard Worker
isValidLevel(int level) const1496*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2D::isValidLevel(int level) const
1497*8975f5c5SAndroid Build Coastguard Worker {
1498*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false);
1499*8975f5c5SAndroid Build Coastguard Worker }
1500*8975f5c5SAndroid Build Coastguard Worker
isLevelComplete(int level) const1501*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2D::isLevelComplete(int level) const
1502*8975f5c5SAndroid Build Coastguard Worker {
1503*8975f5c5SAndroid Build Coastguard Worker if (isImmutable())
1504*8975f5c5SAndroid Build Coastguard Worker {
1505*8975f5c5SAndroid Build Coastguard Worker return true;
1506*8975f5c5SAndroid Build Coastguard Worker }
1507*8975f5c5SAndroid Build Coastguard Worker
1508*8975f5c5SAndroid Build Coastguard Worker GLsizei width = getLevelZeroWidth();
1509*8975f5c5SAndroid Build Coastguard Worker GLsizei height = getLevelZeroHeight();
1510*8975f5c5SAndroid Build Coastguard Worker
1511*8975f5c5SAndroid Build Coastguard Worker if (width <= 0 || height <= 0)
1512*8975f5c5SAndroid Build Coastguard Worker {
1513*8975f5c5SAndroid Build Coastguard Worker return false;
1514*8975f5c5SAndroid Build Coastguard Worker }
1515*8975f5c5SAndroid Build Coastguard Worker
1516*8975f5c5SAndroid Build Coastguard Worker // The base image level is complete if the width and height are positive
1517*8975f5c5SAndroid Build Coastguard Worker if (level == static_cast<int>(getBaseLevel()))
1518*8975f5c5SAndroid Build Coastguard Worker {
1519*8975f5c5SAndroid Build Coastguard Worker return true;
1520*8975f5c5SAndroid Build Coastguard Worker }
1521*8975f5c5SAndroid Build Coastguard Worker
1522*8975f5c5SAndroid Build Coastguard Worker ASSERT(level >= 0 && level <= static_cast<int>(mImageArray.size()) &&
1523*8975f5c5SAndroid Build Coastguard Worker mImageArray[level] != nullptr);
1524*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = mImageArray[level].get();
1525*8975f5c5SAndroid Build Coastguard Worker
1526*8975f5c5SAndroid Build Coastguard Worker if (image->getInternalFormat() != getBaseLevelInternalFormat())
1527*8975f5c5SAndroid Build Coastguard Worker {
1528*8975f5c5SAndroid Build Coastguard Worker return false;
1529*8975f5c5SAndroid Build Coastguard Worker }
1530*8975f5c5SAndroid Build Coastguard Worker
1531*8975f5c5SAndroid Build Coastguard Worker if (image->getWidth() != std::max(1, width >> level))
1532*8975f5c5SAndroid Build Coastguard Worker {
1533*8975f5c5SAndroid Build Coastguard Worker return false;
1534*8975f5c5SAndroid Build Coastguard Worker }
1535*8975f5c5SAndroid Build Coastguard Worker
1536*8975f5c5SAndroid Build Coastguard Worker if (image->getHeight() != std::max(1, height >> level))
1537*8975f5c5SAndroid Build Coastguard Worker {
1538*8975f5c5SAndroid Build Coastguard Worker return false;
1539*8975f5c5SAndroid Build Coastguard Worker }
1540*8975f5c5SAndroid Build Coastguard Worker
1541*8975f5c5SAndroid Build Coastguard Worker return true;
1542*8975f5c5SAndroid Build Coastguard Worker }
1543*8975f5c5SAndroid Build Coastguard Worker
isImageComplete(const gl::ImageIndex & index) const1544*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2D::isImageComplete(const gl::ImageIndex &index) const
1545*8975f5c5SAndroid Build Coastguard Worker {
1546*8975f5c5SAndroid Build Coastguard Worker return isLevelComplete(index.getLevelIndex());
1547*8975f5c5SAndroid Build Coastguard Worker }
1548*8975f5c5SAndroid Build Coastguard Worker
1549*8975f5c5SAndroid Build Coastguard Worker // Constructs a native texture resource from the texture images
initializeStorage(const gl::Context * context,BindFlags bindFlags)1550*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::initializeStorage(const gl::Context *context, BindFlags bindFlags)
1551*8975f5c5SAndroid Build Coastguard Worker {
1552*8975f5c5SAndroid Build Coastguard Worker // Only initialize the first time this texture is used as a render target or shader resource
1553*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
1554*8975f5c5SAndroid Build Coastguard Worker {
1555*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1556*8975f5c5SAndroid Build Coastguard Worker }
1557*8975f5c5SAndroid Build Coastguard Worker
1558*8975f5c5SAndroid Build Coastguard Worker // do not attempt to create storage for nonexistant data
1559*8975f5c5SAndroid Build Coastguard Worker if (!isLevelComplete(getBaseLevel()))
1560*8975f5c5SAndroid Build Coastguard Worker {
1561*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1562*8975f5c5SAndroid Build Coastguard Worker }
1563*8975f5c5SAndroid Build Coastguard Worker
1564*8975f5c5SAndroid Build Coastguard Worker bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage());
1565*8975f5c5SAndroid Build Coastguard Worker
1566*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage;
1567*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage));
1568*8975f5c5SAndroid Build Coastguard Worker
1569*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
1570*8975f5c5SAndroid Build Coastguard Worker storage.release();
1571*8975f5c5SAndroid Build Coastguard Worker
1572*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
1573*8975f5c5SAndroid Build Coastguard Worker
1574*8975f5c5SAndroid Build Coastguard Worker // flush image data to the storage
1575*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
1576*8975f5c5SAndroid Build Coastguard Worker
1577*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1578*8975f5c5SAndroid Build Coastguard Worker }
1579*8975f5c5SAndroid Build Coastguard Worker
createCompleteStorage(const gl::Context * context,BindFlags bindFlags,TexStoragePointer * outStorage) const1580*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::createCompleteStorage(const gl::Context *context,
1581*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags,
1582*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer *outStorage) const
1583*8975f5c5SAndroid Build Coastguard Worker {
1584*8975f5c5SAndroid Build Coastguard Worker GLsizei width = getLevelZeroWidth();
1585*8975f5c5SAndroid Build Coastguard Worker GLsizei height = getLevelZeroHeight();
1586*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat = getBaseLevelInternalFormat();
1587*8975f5c5SAndroid Build Coastguard Worker
1588*8975f5c5SAndroid Build Coastguard Worker ASSERT(width > 0 && height > 0);
1589*8975f5c5SAndroid Build Coastguard Worker
1590*8975f5c5SAndroid Build Coastguard Worker // use existing storage level count, when previously specified by TexStorage*D
1591*8975f5c5SAndroid Build Coastguard Worker GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
1592*8975f5c5SAndroid Build Coastguard Worker
1593*8975f5c5SAndroid Build Coastguard Worker bool hintLevelZeroOnly = false;
1594*8975f5c5SAndroid Build Coastguard Worker if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
1595*8975f5c5SAndroid Build Coastguard Worker {
1596*8975f5c5SAndroid Build Coastguard Worker // If any of the CPU images (levels >= 1) are dirty, then the textureStorage2D should use
1597*8975f5c5SAndroid Build Coastguard Worker // the mipped texture to begin with. Otherwise, it should use the level-zero-only texture.
1598*8975f5c5SAndroid Build Coastguard Worker hintLevelZeroOnly = true;
1599*8975f5c5SAndroid Build Coastguard Worker for (int level = 1; level < levels && hintLevelZeroOnly; level++)
1600*8975f5c5SAndroid Build Coastguard Worker {
1601*8975f5c5SAndroid Build Coastguard Worker hintLevelZeroOnly = !(mImageArray[level]->isDirty() && isLevelComplete(level));
1602*8975f5c5SAndroid Build Coastguard Worker }
1603*8975f5c5SAndroid Build Coastguard Worker }
1604*8975f5c5SAndroid Build Coastguard Worker
1605*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Determine if the texture creation succeeded
1606*8975f5c5SAndroid Build Coastguard Worker *outStorage = {mRenderer->createTextureStorage2D(internalFormat, bindFlags, width, height,
1607*8975f5c5SAndroid Build Coastguard Worker levels, mState.getLabel(), hintLevelZeroOnly),
1608*8975f5c5SAndroid Build Coastguard Worker context};
1609*8975f5c5SAndroid Build Coastguard Worker
1610*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1611*8975f5c5SAndroid Build Coastguard Worker }
1612*8975f5c5SAndroid Build Coastguard Worker
setCompleteTexStorage(const gl::Context * context,TextureStorage * newCompleteTexStorage)1613*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::setCompleteTexStorage(const gl::Context *context,
1614*8975f5c5SAndroid Build Coastguard Worker TextureStorage *newCompleteTexStorage)
1615*8975f5c5SAndroid Build Coastguard Worker {
1616*8975f5c5SAndroid Build Coastguard Worker if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
1617*8975f5c5SAndroid Build Coastguard Worker {
1618*8975f5c5SAndroid Build Coastguard Worker for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
1619*8975f5c5SAndroid Build Coastguard Worker {
1620*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
1621*8975f5c5SAndroid Build Coastguard Worker mImageArray[level]->setManagedSurface2D(context, newCompleteTexStorage, level));
1622*8975f5c5SAndroid Build Coastguard Worker }
1623*8975f5c5SAndroid Build Coastguard Worker }
1624*8975f5c5SAndroid Build Coastguard Worker
1625*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask copyImageMask;
1626*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set();
1627*8975f5c5SAndroid Build Coastguard Worker
1628*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, copyImageMask));
1629*8975f5c5SAndroid Build Coastguard Worker mTexStorage = newCompleteTexStorage;
1630*8975f5c5SAndroid Build Coastguard Worker mTexStorageObserverBinding.bind(mTexStorage);
1631*8975f5c5SAndroid Build Coastguard Worker
1632*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
1633*8975f5c5SAndroid Build Coastguard Worker
1634*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1635*8975f5c5SAndroid Build Coastguard Worker }
1636*8975f5c5SAndroid Build Coastguard Worker
updateStorage(const gl::Context * context)1637*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::updateStorage(const gl::Context *context)
1638*8975f5c5SAndroid Build Coastguard Worker {
1639*8975f5c5SAndroid Build Coastguard Worker if (!mDirtyImages)
1640*8975f5c5SAndroid Build Coastguard Worker {
1641*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1642*8975f5c5SAndroid Build Coastguard Worker }
1643*8975f5c5SAndroid Build Coastguard Worker
1644*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage != nullptr);
1645*8975f5c5SAndroid Build Coastguard Worker GLint storageLevels = mTexStorage->getLevelCount();
1646*8975f5c5SAndroid Build Coastguard Worker for (int level = 0; level < storageLevels; level++)
1647*8975f5c5SAndroid Build Coastguard Worker {
1648*8975f5c5SAndroid Build Coastguard Worker if (mImageArray[level]->isDirty() && isLevelComplete(level))
1649*8975f5c5SAndroid Build Coastguard Worker {
1650*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, level));
1651*8975f5c5SAndroid Build Coastguard Worker }
1652*8975f5c5SAndroid Build Coastguard Worker }
1653*8975f5c5SAndroid Build Coastguard Worker
1654*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = false;
1655*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1656*8975f5c5SAndroid Build Coastguard Worker }
1657*8975f5c5SAndroid Build Coastguard Worker
updateStorageLevel(const gl::Context * context,int level)1658*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::updateStorageLevel(const gl::Context *context, int level)
1659*8975f5c5SAndroid Build Coastguard Worker {
1660*8975f5c5SAndroid Build Coastguard Worker ASSERT(level <= static_cast<int>(mImageArray.size()) && mImageArray[level] != nullptr);
1661*8975f5c5SAndroid Build Coastguard Worker ASSERT(isLevelComplete(level));
1662*8975f5c5SAndroid Build Coastguard Worker
1663*8975f5c5SAndroid Build Coastguard Worker if (mImageArray[level]->isDirty())
1664*8975f5c5SAndroid Build Coastguard Worker {
1665*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex index = gl::ImageIndex::Make2D(level);
1666*8975f5c5SAndroid Build Coastguard Worker gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
1667*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, region));
1668*8975f5c5SAndroid Build Coastguard Worker }
1669*8975f5c5SAndroid Build Coastguard Worker
1670*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1671*8975f5c5SAndroid Build Coastguard Worker }
1672*8975f5c5SAndroid Build Coastguard Worker
redefineImage(const gl::Context * context,size_t level,GLenum internalformat,const gl::Extents & size,bool forceRelease)1673*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2D::redefineImage(const gl::Context *context,
1674*8975f5c5SAndroid Build Coastguard Worker size_t level,
1675*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
1676*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
1677*8975f5c5SAndroid Build Coastguard Worker bool forceRelease)
1678*8975f5c5SAndroid Build Coastguard Worker {
1679*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.depth == 1);
1680*8975f5c5SAndroid Build Coastguard Worker
1681*8975f5c5SAndroid Build Coastguard Worker // If there currently is a corresponding storage texture image, it has these parameters
1682*8975f5c5SAndroid Build Coastguard Worker const int storageWidth = std::max(1, getLevelZeroWidth() >> level);
1683*8975f5c5SAndroid Build Coastguard Worker const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
1684*8975f5c5SAndroid Build Coastguard Worker const GLenum storageFormat = getBaseLevelInternalFormat();
1685*8975f5c5SAndroid Build Coastguard Worker
1686*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
1687*8975f5c5SAndroid Build Coastguard Worker {
1688*8975f5c5SAndroid Build Coastguard Worker const size_t storageLevels = mTexStorage->getLevelCount();
1689*8975f5c5SAndroid Build Coastguard Worker
1690*8975f5c5SAndroid Build Coastguard Worker // If the storage was from an EGL image, copy it back into local images to preserve it
1691*8975f5c5SAndroid Build Coastguard Worker // while orphaning
1692*8975f5c5SAndroid Build Coastguard Worker if (level != 0 && mEGLImageTarget)
1693*8975f5c5SAndroid Build Coastguard Worker {
1694*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageArray[0]->copyFromTexStorage(context, gl::ImageIndex::Make2D(0),
1695*8975f5c5SAndroid Build Coastguard Worker mTexStorage));
1696*8975f5c5SAndroid Build Coastguard Worker }
1697*8975f5c5SAndroid Build Coastguard Worker
1698*8975f5c5SAndroid Build Coastguard Worker if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
1699*8975f5c5SAndroid Build Coastguard Worker size.height != storageHeight || internalformat != storageFormat ||
1700*8975f5c5SAndroid Build Coastguard Worker mEGLImageTarget) // Discard mismatched storage
1701*8975f5c5SAndroid Build Coastguard Worker {
1702*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask copyImageMask;
1703*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set();
1704*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set(level, false);
1705*8975f5c5SAndroid Build Coastguard Worker
1706*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, copyImageMask));
1707*8975f5c5SAndroid Build Coastguard Worker markAllImagesDirty();
1708*8975f5c5SAndroid Build Coastguard Worker }
1709*8975f5c5SAndroid Build Coastguard Worker }
1710*8975f5c5SAndroid Build Coastguard Worker
1711*8975f5c5SAndroid Build Coastguard Worker mImageArray[level]->redefine(gl::TextureType::_2D, internalformat, size, forceRelease);
1712*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = mDirtyImages || mImageArray[level]->isDirty();
1713*8975f5c5SAndroid Build Coastguard Worker
1714*8975f5c5SAndroid Build Coastguard Worker // Can't be an EGL image target after being redefined
1715*8975f5c5SAndroid Build Coastguard Worker mEGLImageTarget = false;
1716*8975f5c5SAndroid Build Coastguard Worker
1717*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1718*8975f5c5SAndroid Build Coastguard Worker }
1719*8975f5c5SAndroid Build Coastguard Worker
imageIterator() const1720*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator TextureD3D_2D::imageIterator() const
1721*8975f5c5SAndroid Build Coastguard Worker {
1722*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
1723*8975f5c5SAndroid Build Coastguard Worker }
1724*8975f5c5SAndroid Build Coastguard Worker
getImageIndex(GLint mip,GLint) const1725*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex TextureD3D_2D::getImageIndex(GLint mip, GLint /*layer*/) const
1726*8975f5c5SAndroid Build Coastguard Worker {
1727*8975f5c5SAndroid Build Coastguard Worker // "layer" does not apply to 2D Textures.
1728*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndex::Make2D(mip);
1729*8975f5c5SAndroid Build Coastguard Worker }
1730*8975f5c5SAndroid Build Coastguard Worker
isValidIndex(const gl::ImageIndex & index) const1731*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2D::isValidIndex(const gl::ImageIndex &index) const
1732*8975f5c5SAndroid Build Coastguard Worker {
1733*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage && index.getType() == gl::TextureType::_2D && index.getLevelIndex() >= 0 &&
1734*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex() < mTexStorage->getLevelCount());
1735*8975f5c5SAndroid Build Coastguard Worker }
1736*8975f5c5SAndroid Build Coastguard Worker
markAllImagesDirty()1737*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_2D::markAllImagesDirty()
1738*8975f5c5SAndroid Build Coastguard Worker {
1739*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1740*8975f5c5SAndroid Build Coastguard Worker {
1741*8975f5c5SAndroid Build Coastguard Worker mImageArray[i]->markDirty();
1742*8975f5c5SAndroid Build Coastguard Worker }
1743*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
1744*8975f5c5SAndroid Build Coastguard Worker }
1745*8975f5c5SAndroid Build Coastguard Worker
TextureD3D_Cube(const gl::TextureState & state,RendererD3D * renderer)1746*8975f5c5SAndroid Build Coastguard Worker TextureD3D_Cube::TextureD3D_Cube(const gl::TextureState &state, RendererD3D *renderer)
1747*8975f5c5SAndroid Build Coastguard Worker : TextureD3D(state, renderer)
1748*8975f5c5SAndroid Build Coastguard Worker {
1749*8975f5c5SAndroid Build Coastguard Worker for (auto &face : mImageArray)
1750*8975f5c5SAndroid Build Coastguard Worker {
1751*8975f5c5SAndroid Build Coastguard Worker for (auto &image : face)
1752*8975f5c5SAndroid Build Coastguard Worker {
1753*8975f5c5SAndroid Build Coastguard Worker image.reset(renderer->createImage());
1754*8975f5c5SAndroid Build Coastguard Worker }
1755*8975f5c5SAndroid Build Coastguard Worker }
1756*8975f5c5SAndroid Build Coastguard Worker }
1757*8975f5c5SAndroid Build Coastguard Worker
onDestroy(const gl::Context * context)1758*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_Cube::onDestroy(const gl::Context *context)
1759*8975f5c5SAndroid Build Coastguard Worker {
1760*8975f5c5SAndroid Build Coastguard Worker // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage
1761*8975f5c5SAndroid Build Coastguard Worker // for some of their data. If TextureStorage is deleted before the Images, then their data will
1762*8975f5c5SAndroid Build Coastguard Worker // be wastefully copied back from the GPU before we delete the Images.
1763*8975f5c5SAndroid Build Coastguard Worker for (auto &face : mImageArray)
1764*8975f5c5SAndroid Build Coastguard Worker {
1765*8975f5c5SAndroid Build Coastguard Worker for (auto &image : face)
1766*8975f5c5SAndroid Build Coastguard Worker {
1767*8975f5c5SAndroid Build Coastguard Worker image.reset();
1768*8975f5c5SAndroid Build Coastguard Worker }
1769*8975f5c5SAndroid Build Coastguard Worker }
1770*8975f5c5SAndroid Build Coastguard Worker return TextureD3D::onDestroy(context);
1771*8975f5c5SAndroid Build Coastguard Worker }
1772*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D_Cube()1773*8975f5c5SAndroid Build Coastguard Worker TextureD3D_Cube::~TextureD3D_Cube() {}
1774*8975f5c5SAndroid Build Coastguard Worker
getImage(int level,int layer) const1775*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_Cube::getImage(int level, int layer) const
1776*8975f5c5SAndroid Build Coastguard Worker {
1777*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1778*8975f5c5SAndroid Build Coastguard Worker ASSERT(layer >= 0 && static_cast<size_t>(layer) < gl::kCubeFaceCount);
1779*8975f5c5SAndroid Build Coastguard Worker return mImageArray[layer][level].get();
1780*8975f5c5SAndroid Build Coastguard Worker }
1781*8975f5c5SAndroid Build Coastguard Worker
getImage(const gl::ImageIndex & index) const1782*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const
1783*8975f5c5SAndroid Build Coastguard Worker {
1784*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1785*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::IsCubeMapFaceTarget(index.getTarget()));
1786*8975f5c5SAndroid Build Coastguard Worker return mImageArray[index.cubeMapFaceIndex()][index.getLevelIndex()].get();
1787*8975f5c5SAndroid Build Coastguard Worker }
1788*8975f5c5SAndroid Build Coastguard Worker
getLayerCount(int level) const1789*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_Cube::getLayerCount(int level) const
1790*8975f5c5SAndroid Build Coastguard Worker {
1791*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1792*8975f5c5SAndroid Build Coastguard Worker return gl::kCubeFaceCount;
1793*8975f5c5SAndroid Build Coastguard Worker }
1794*8975f5c5SAndroid Build Coastguard Worker
getInternalFormat(GLint level,GLint layer) const1795*8975f5c5SAndroid Build Coastguard Worker GLenum TextureD3D_Cube::getInternalFormat(GLint level, GLint layer) const
1796*8975f5c5SAndroid Build Coastguard Worker {
1797*8975f5c5SAndroid Build Coastguard Worker if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1798*8975f5c5SAndroid Build Coastguard Worker return mImageArray[layer][level]->getInternalFormat();
1799*8975f5c5SAndroid Build Coastguard Worker else
1800*8975f5c5SAndroid Build Coastguard Worker return GL_NONE;
1801*8975f5c5SAndroid Build Coastguard Worker }
1802*8975f5c5SAndroid Build Coastguard Worker
isDepth(GLint level,GLint layer) const1803*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const
1804*8975f5c5SAndroid Build Coastguard Worker {
1805*8975f5c5SAndroid Build Coastguard Worker return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0;
1806*8975f5c5SAndroid Build Coastguard Worker }
1807*8975f5c5SAndroid Build Coastguard Worker
isSRGB(GLint level,GLint layer) const1808*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Cube::isSRGB(GLint level, GLint layer) const
1809*8975f5c5SAndroid Build Coastguard Worker {
1810*8975f5c5SAndroid Build Coastguard Worker return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).colorEncoding == GL_SRGB;
1811*8975f5c5SAndroid Build Coastguard Worker }
1812*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)1813*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::setEGLImageTarget(const gl::Context *context,
1814*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
1815*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
1816*8975f5c5SAndroid Build Coastguard Worker {
1817*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
1818*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1819*8975f5c5SAndroid Build Coastguard Worker }
1820*8975f5c5SAndroid Build Coastguard Worker
setImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)1821*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::setImage(const gl::Context *context,
1822*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1823*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1824*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
1825*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1826*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1827*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
1828*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
1829*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1830*8975f5c5SAndroid Build Coastguard Worker {
1831*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.depth == 1);
1832*8975f5c5SAndroid Build Coastguard Worker
1833*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
1834*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), index.getLevelIndex(),
1835*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.sizedInternalFormat, size, false));
1836*8975f5c5SAndroid Build Coastguard Worker
1837*8975f5c5SAndroid Build Coastguard Worker return setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0);
1838*8975f5c5SAndroid Build Coastguard Worker }
1839*8975f5c5SAndroid Build Coastguard Worker
setSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)1840*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::setSubImage(const gl::Context *context,
1841*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1842*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
1843*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1844*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1845*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
1846*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
1847*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1848*8975f5c5SAndroid Build Coastguard Worker {
1849*8975f5c5SAndroid Build Coastguard Worker ASSERT(area.depth == 1 && area.z == 0);
1850*8975f5c5SAndroid Build Coastguard Worker return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, pixels,
1851*8975f5c5SAndroid Build Coastguard Worker 0);
1852*8975f5c5SAndroid Build Coastguard Worker }
1853*8975f5c5SAndroid Build Coastguard Worker
setCompressedImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)1854*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::setCompressedImage(const gl::Context *context,
1855*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1856*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1857*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
1858*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
1859*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
1860*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1861*8975f5c5SAndroid Build Coastguard Worker {
1862*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.depth == 1);
1863*8975f5c5SAndroid Build Coastguard Worker
1864*8975f5c5SAndroid Build Coastguard Worker // compressed formats don't have separate sized internal formats-- we can just use the
1865*8975f5c5SAndroid Build Coastguard Worker // compressed format directly
1866*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), index.getLevelIndex(),
1867*8975f5c5SAndroid Build Coastguard Worker internalFormat, size, false));
1868*8975f5c5SAndroid Build Coastguard Worker
1869*8975f5c5SAndroid Build Coastguard Worker return setCompressedImageImpl(context, index, unpack, pixels, 0);
1870*8975f5c5SAndroid Build Coastguard Worker }
1871*8975f5c5SAndroid Build Coastguard Worker
setCompressedSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)1872*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::setCompressedSubImage(const gl::Context *context,
1873*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1874*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
1875*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1876*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
1877*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
1878*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1879*8975f5c5SAndroid Build Coastguard Worker {
1880*8975f5c5SAndroid Build Coastguard Worker ASSERT(area.depth == 1 && area.z == 0);
1881*8975f5c5SAndroid Build Coastguard Worker
1882*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
1883*8975f5c5SAndroid Build Coastguard Worker return commitRegion(context, index, area);
1884*8975f5c5SAndroid Build Coastguard Worker }
1885*8975f5c5SAndroid Build Coastguard Worker
copyImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Rectangle & sourceArea,GLenum internalFormat,gl::Framebuffer * source)1886*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::copyImage(const gl::Context *context,
1887*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1888*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
1889*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1890*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
1891*8975f5c5SAndroid Build Coastguard Worker {
1892*8975f5c5SAndroid Build Coastguard Worker GLint faceIndex = index.cubeMapFaceIndex();
1893*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
1894*8975f5c5SAndroid Build Coastguard Worker gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
1895*8975f5c5SAndroid Build Coastguard Worker
1896*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(sourceArea.width, sourceArea.height, 1);
1897*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, faceIndex, index.getLevelIndex(),
1898*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.sizedInternalFormat, size, false));
1899*8975f5c5SAndroid Build Coastguard Worker
1900*8975f5c5SAndroid Build Coastguard Worker gl::Extents fbSize = source->getReadColorAttachment()->getSize();
1901*8975f5c5SAndroid Build Coastguard Worker
1902*8975f5c5SAndroid Build Coastguard Worker // Does the read area extend beyond the framebuffer?
1903*8975f5c5SAndroid Build Coastguard Worker bool outside = sourceArea.x < 0 || sourceArea.y < 0 ||
1904*8975f5c5SAndroid Build Coastguard Worker sourceArea.x + sourceArea.width > fbSize.width ||
1905*8975f5c5SAndroid Build Coastguard Worker sourceArea.y + sourceArea.height > fbSize.height;
1906*8975f5c5SAndroid Build Coastguard Worker
1907*8975f5c5SAndroid Build Coastguard Worker // WebGL requires that pixels that would be outside the framebuffer are treated as zero values,
1908*8975f5c5SAndroid Build Coastguard Worker // so clear the mip level to 0 prior to making the copy if any pixel would be sampled outside.
1909*8975f5c5SAndroid Build Coastguard Worker // Same thing for robust resource init.
1910*8975f5c5SAndroid Build Coastguard Worker if (outside && (context->isWebGL() || context->isRobustResourceInitEnabled()))
1911*8975f5c5SAndroid Build Coastguard Worker {
1912*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeContents(context, GL_NONE, index));
1913*8975f5c5SAndroid Build Coastguard Worker }
1914*8975f5c5SAndroid Build Coastguard Worker
1915*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedArea;
1916*8975f5c5SAndroid Build Coastguard Worker if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
1917*8975f5c5SAndroid Build Coastguard Worker {
1918*8975f5c5SAndroid Build Coastguard Worker // Empty source area, nothing to do.
1919*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1920*8975f5c5SAndroid Build Coastguard Worker }
1921*8975f5c5SAndroid Build Coastguard Worker
1922*8975f5c5SAndroid Build Coastguard Worker gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0);
1923*8975f5c5SAndroid Build Coastguard Worker
1924*8975f5c5SAndroid Build Coastguard Worker // If the zero max LOD workaround is active, then we can't sample from individual layers of the
1925*8975f5c5SAndroid Build Coastguard Worker // framebuffer in shaders, so we should use the non-rendering copy path.
1926*8975f5c5SAndroid Build Coastguard Worker if (!canCreateRenderTargetForImage(index) ||
1927*8975f5c5SAndroid Build Coastguard Worker mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
1928*8975f5c5SAndroid Build Coastguard Worker {
1929*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageArray[faceIndex][index.getLevelIndex()]->copyFromFramebuffer(
1930*8975f5c5SAndroid Build Coastguard Worker context, destOffset, clippedArea, source));
1931*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
1932*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1933*8975f5c5SAndroid Build Coastguard Worker }
1934*8975f5c5SAndroid Build Coastguard Worker else
1935*8975f5c5SAndroid Build Coastguard Worker {
1936*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
1937*8975f5c5SAndroid Build Coastguard Worker
1938*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.width == size.height);
1939*8975f5c5SAndroid Build Coastguard Worker
1940*8975f5c5SAndroid Build Coastguard Worker if (size.width > 0 && isValidFaceLevel(faceIndex, index.getLevelIndex()))
1941*8975f5c5SAndroid Build Coastguard Worker {
1942*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex()));
1943*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImageCube(context, source, clippedArea, internalFormat,
1944*8975f5c5SAndroid Build Coastguard Worker destOffset, mTexStorage, index.getTarget(),
1945*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex()));
1946*8975f5c5SAndroid Build Coastguard Worker }
1947*8975f5c5SAndroid Build Coastguard Worker }
1948*8975f5c5SAndroid Build Coastguard Worker
1949*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1950*8975f5c5SAndroid Build Coastguard Worker }
1951*8975f5c5SAndroid Build Coastguard Worker
copySubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,const gl::Rectangle & sourceArea,gl::Framebuffer * source)1952*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::copySubImage(const gl::Context *context,
1953*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1954*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
1955*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
1956*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
1957*8975f5c5SAndroid Build Coastguard Worker {
1958*8975f5c5SAndroid Build Coastguard Worker gl::Extents fbSize = source->getReadColorAttachment()->getSize();
1959*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedArea;
1960*8975f5c5SAndroid Build Coastguard Worker if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
1961*8975f5c5SAndroid Build Coastguard Worker {
1962*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1963*8975f5c5SAndroid Build Coastguard Worker }
1964*8975f5c5SAndroid Build Coastguard Worker const gl::Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x,
1965*8975f5c5SAndroid Build Coastguard Worker destOffset.y + clippedArea.y - sourceArea.y, 0);
1966*8975f5c5SAndroid Build Coastguard Worker
1967*8975f5c5SAndroid Build Coastguard Worker GLint faceIndex = index.cubeMapFaceIndex();
1968*8975f5c5SAndroid Build Coastguard Worker
1969*8975f5c5SAndroid Build Coastguard Worker // If the zero max LOD workaround is active, then we can't sample from individual layers of the
1970*8975f5c5SAndroid Build Coastguard Worker // framebuffer in shaders, so we should use the non-rendering copy path.
1971*8975f5c5SAndroid Build Coastguard Worker if (!canCreateRenderTargetForImage(index) ||
1972*8975f5c5SAndroid Build Coastguard Worker mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
1973*8975f5c5SAndroid Build Coastguard Worker {
1974*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageArray[faceIndex][index.getLevelIndex()]->copyFromFramebuffer(
1975*8975f5c5SAndroid Build Coastguard Worker context, clippedOffset, clippedArea, source));
1976*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
1977*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1978*8975f5c5SAndroid Build Coastguard Worker }
1979*8975f5c5SAndroid Build Coastguard Worker else
1980*8975f5c5SAndroid Build Coastguard Worker {
1981*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
1982*8975f5c5SAndroid Build Coastguard Worker if (isValidFaceLevel(faceIndex, index.getLevelIndex()))
1983*8975f5c5SAndroid Build Coastguard Worker {
1984*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex()));
1985*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImageCube(
1986*8975f5c5SAndroid Build Coastguard Worker context, source, clippedArea, gl::GetUnsizedFormat(getBaseLevelInternalFormat()),
1987*8975f5c5SAndroid Build Coastguard Worker clippedOffset, mTexStorage, index.getTarget(), index.getLevelIndex()));
1988*8975f5c5SAndroid Build Coastguard Worker }
1989*8975f5c5SAndroid Build Coastguard Worker }
1990*8975f5c5SAndroid Build Coastguard Worker
1991*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1992*8975f5c5SAndroid Build Coastguard Worker }
1993*8975f5c5SAndroid Build Coastguard Worker
copyTexture(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,GLenum type,GLint sourceLevel,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)1994*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::copyTexture(const gl::Context *context,
1995*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1996*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1997*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1998*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
1999*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
2000*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
2001*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
2002*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
2003*8975f5c5SAndroid Build Coastguard Worker {
2004*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::IsCubeMapFaceTarget(index.getTarget()));
2005*8975f5c5SAndroid Build Coastguard Worker
2006*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget sourceTarget = NonCubeTextureTypeToTarget(source->getType());
2007*8975f5c5SAndroid Build Coastguard Worker
2008*8975f5c5SAndroid Build Coastguard Worker GLint faceIndex = index.cubeMapFaceIndex();
2009*8975f5c5SAndroid Build Coastguard Worker
2010*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
2011*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)),
2012*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1);
2013*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, faceIndex, index.getLevelIndex(),
2014*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.sizedInternalFormat, size, false));
2015*8975f5c5SAndroid Build Coastguard Worker
2016*8975f5c5SAndroid Build Coastguard Worker gl::Box sourceBox(0, 0, 0, size.width, size.height, 1);
2017*8975f5c5SAndroid Build Coastguard Worker gl::Offset destOffset(0, 0, 0);
2018*8975f5c5SAndroid Build Coastguard Worker
2019*8975f5c5SAndroid Build Coastguard Worker if (!isSRGB(index.getLevelIndex(), faceIndex) && canCreateRenderTargetForImage(index))
2020*8975f5c5SAndroid Build Coastguard Worker {
2021*8975f5c5SAndroid Build Coastguard Worker
2022*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
2023*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidFaceLevel(faceIndex, index.getLevelIndex()));
2024*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex()));
2025*8975f5c5SAndroid Build Coastguard Worker
2026*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D,
2027*8975f5c5SAndroid Build Coastguard Worker sourceBox, internalFormatInfo.format,
2028*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type, destOffset, mTexStorage,
2029*8975f5c5SAndroid Build Coastguard Worker index.getTarget(), index.getLevelIndex(), unpackFlipY,
2030*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
2031*8975f5c5SAndroid Build Coastguard Worker }
2032*8975f5c5SAndroid Build Coastguard Worker else
2033*8975f5c5SAndroid Build Coastguard Worker {
2034*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel);
2035*8975f5c5SAndroid Build Coastguard Worker TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
2036*8975f5c5SAndroid Build Coastguard Worker ImageD3D *sourceImage = nullptr;
2037*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
2038*8975f5c5SAndroid Build Coastguard Worker
2039*8975f5c5SAndroid Build Coastguard Worker ImageD3D *destImage = nullptr;
2040*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
2041*8975f5c5SAndroid Build Coastguard Worker
2042*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
2043*8975f5c5SAndroid Build Coastguard Worker unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
2044*8975f5c5SAndroid Build Coastguard Worker
2045*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
2046*8975f5c5SAndroid Build Coastguard Worker
2047*8975f5c5SAndroid Build Coastguard Worker gl::Box destRegion(destOffset, size);
2048*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, destRegion));
2049*8975f5c5SAndroid Build Coastguard Worker }
2050*8975f5c5SAndroid Build Coastguard Worker
2051*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2052*8975f5c5SAndroid Build Coastguard Worker }
2053*8975f5c5SAndroid Build Coastguard Worker
copySubTexture(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,GLint sourceLevel,const gl::Box & sourceBox,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)2054*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::copySubTexture(const gl::Context *context,
2055*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2056*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
2057*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
2058*8975f5c5SAndroid Build Coastguard Worker const gl::Box &sourceBox,
2059*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
2060*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
2061*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
2062*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
2063*8975f5c5SAndroid Build Coastguard Worker {
2064*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::IsCubeMapFaceTarget(index.getTarget()));
2065*8975f5c5SAndroid Build Coastguard Worker
2066*8975f5c5SAndroid Build Coastguard Worker GLint faceIndex = index.cubeMapFaceIndex();
2067*8975f5c5SAndroid Build Coastguard Worker
2068*8975f5c5SAndroid Build Coastguard Worker if (!isSRGB(index.getLevelIndex(), faceIndex) && canCreateRenderTargetForImage(index))
2069*8975f5c5SAndroid Build Coastguard Worker {
2070*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
2071*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidFaceLevel(faceIndex, index.getLevelIndex()));
2072*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex()));
2073*8975f5c5SAndroid Build Coastguard Worker
2074*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
2075*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex(), faceIndex));
2076*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D,
2077*8975f5c5SAndroid Build Coastguard Worker sourceBox, internalFormatInfo.format,
2078*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type, destOffset, mTexStorage,
2079*8975f5c5SAndroid Build Coastguard Worker index.getTarget(), index.getLevelIndex(), unpackFlipY,
2080*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
2081*8975f5c5SAndroid Build Coastguard Worker }
2082*8975f5c5SAndroid Build Coastguard Worker else
2083*8975f5c5SAndroid Build Coastguard Worker {
2084*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel);
2085*8975f5c5SAndroid Build Coastguard Worker TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
2086*8975f5c5SAndroid Build Coastguard Worker ImageD3D *sourceImage = nullptr;
2087*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
2088*8975f5c5SAndroid Build Coastguard Worker
2089*8975f5c5SAndroid Build Coastguard Worker ImageD3D *destImage = nullptr;
2090*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
2091*8975f5c5SAndroid Build Coastguard Worker
2092*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
2093*8975f5c5SAndroid Build Coastguard Worker unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
2094*8975f5c5SAndroid Build Coastguard Worker
2095*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
2096*8975f5c5SAndroid Build Coastguard Worker
2097*8975f5c5SAndroid Build Coastguard Worker gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceBox.width, sourceBox.height, 1);
2098*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, destRegion));
2099*8975f5c5SAndroid Build Coastguard Worker }
2100*8975f5c5SAndroid Build Coastguard Worker
2101*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2102*8975f5c5SAndroid Build Coastguard Worker }
2103*8975f5c5SAndroid Build Coastguard Worker
setStorage(const gl::Context * context,gl::TextureType type,size_t levels,GLenum internalFormat,const gl::Extents & size)2104*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::setStorage(const gl::Context *context,
2105*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
2106*8975f5c5SAndroid Build Coastguard Worker size_t levels,
2107*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
2108*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size)
2109*8975f5c5SAndroid Build Coastguard Worker {
2110*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.width == size.height);
2111*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.depth == 1);
2112*8975f5c5SAndroid Build Coastguard Worker
2113*8975f5c5SAndroid Build Coastguard Worker for (size_t level = 0; level < levels; level++)
2114*8975f5c5SAndroid Build Coastguard Worker {
2115*8975f5c5SAndroid Build Coastguard Worker GLsizei mipSize = std::max(1, size.width >> level);
2116*8975f5c5SAndroid Build Coastguard Worker for (size_t faceIndex = 0; faceIndex < gl::kCubeFaceCount; faceIndex++)
2117*8975f5c5SAndroid Build Coastguard Worker {
2118*8975f5c5SAndroid Build Coastguard Worker mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, internalFormat,
2119*8975f5c5SAndroid Build Coastguard Worker gl::Extents(mipSize, mipSize, 1), true);
2120*8975f5c5SAndroid Build Coastguard Worker }
2121*8975f5c5SAndroid Build Coastguard Worker }
2122*8975f5c5SAndroid Build Coastguard Worker
2123*8975f5c5SAndroid Build Coastguard Worker for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
2124*8975f5c5SAndroid Build Coastguard Worker {
2125*8975f5c5SAndroid Build Coastguard Worker for (size_t faceIndex = 0; faceIndex < gl::kCubeFaceCount; faceIndex++)
2126*8975f5c5SAndroid Build Coastguard Worker {
2127*8975f5c5SAndroid Build Coastguard Worker mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, GL_NONE,
2128*8975f5c5SAndroid Build Coastguard Worker gl::Extents(0, 0, 0), true);
2129*8975f5c5SAndroid Build Coastguard Worker }
2130*8975f5c5SAndroid Build Coastguard Worker }
2131*8975f5c5SAndroid Build Coastguard Worker
2132*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Verify storage creation had no errors
2133*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags;
2134*8975f5c5SAndroid Build Coastguard Worker bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage());
2135*8975f5c5SAndroid Build Coastguard Worker
2136*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage = {
2137*8975f5c5SAndroid Build Coastguard Worker mRenderer->createTextureStorageCube(internalFormat, bindFlags, size.width,
2138*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(levels), false, mState.getLabel()),
2139*8975f5c5SAndroid Build Coastguard Worker context};
2140*8975f5c5SAndroid Build Coastguard Worker
2141*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
2142*8975f5c5SAndroid Build Coastguard Worker storage.release();
2143*8975f5c5SAndroid Build Coastguard Worker
2144*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
2145*8975f5c5SAndroid Build Coastguard Worker
2146*8975f5c5SAndroid Build Coastguard Worker mImmutable = true;
2147*8975f5c5SAndroid Build Coastguard Worker
2148*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2149*8975f5c5SAndroid Build Coastguard Worker }
2150*8975f5c5SAndroid Build Coastguard Worker
2151*8975f5c5SAndroid Build Coastguard Worker // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
isCubeComplete() const2152*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Cube::isCubeComplete() const
2153*8975f5c5SAndroid Build Coastguard Worker {
2154*8975f5c5SAndroid Build Coastguard Worker int baseWidth = getBaseLevelWidth();
2155*8975f5c5SAndroid Build Coastguard Worker int baseHeight = getBaseLevelHeight();
2156*8975f5c5SAndroid Build Coastguard Worker GLenum baseFormat = getBaseLevelInternalFormat();
2157*8975f5c5SAndroid Build Coastguard Worker
2158*8975f5c5SAndroid Build Coastguard Worker if (baseWidth <= 0 || baseWidth != baseHeight)
2159*8975f5c5SAndroid Build Coastguard Worker {
2160*8975f5c5SAndroid Build Coastguard Worker return false;
2161*8975f5c5SAndroid Build Coastguard Worker }
2162*8975f5c5SAndroid Build Coastguard Worker
2163*8975f5c5SAndroid Build Coastguard Worker for (size_t faceIndex = 1; faceIndex < gl::kCubeFaceCount; faceIndex++)
2164*8975f5c5SAndroid Build Coastguard Worker {
2165*8975f5c5SAndroid Build Coastguard Worker const ImageD3D &faceBaseImage = *mImageArray[faceIndex][getBaseLevel()];
2166*8975f5c5SAndroid Build Coastguard Worker
2167*8975f5c5SAndroid Build Coastguard Worker if (faceBaseImage.getWidth() != baseWidth || faceBaseImage.getHeight() != baseHeight ||
2168*8975f5c5SAndroid Build Coastguard Worker faceBaseImage.getInternalFormat() != baseFormat)
2169*8975f5c5SAndroid Build Coastguard Worker {
2170*8975f5c5SAndroid Build Coastguard Worker return false;
2171*8975f5c5SAndroid Build Coastguard Worker }
2172*8975f5c5SAndroid Build Coastguard Worker }
2173*8975f5c5SAndroid Build Coastguard Worker
2174*8975f5c5SAndroid Build Coastguard Worker return true;
2175*8975f5c5SAndroid Build Coastguard Worker }
2176*8975f5c5SAndroid Build Coastguard Worker
bindTexImage(const gl::Context * context,egl::Surface * surface)2177*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::bindTexImage(const gl::Context *context, egl::Surface *surface)
2178*8975f5c5SAndroid Build Coastguard Worker {
2179*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
2180*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2181*8975f5c5SAndroid Build Coastguard Worker }
2182*8975f5c5SAndroid Build Coastguard Worker
releaseTexImage(const gl::Context * context)2183*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::releaseTexImage(const gl::Context *context)
2184*8975f5c5SAndroid Build Coastguard Worker {
2185*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
2186*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2187*8975f5c5SAndroid Build Coastguard Worker }
2188*8975f5c5SAndroid Build Coastguard Worker
initMipmapImages(const gl::Context * context)2189*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::initMipmapImages(const gl::Context *context)
2190*8975f5c5SAndroid Build Coastguard Worker {
2191*8975f5c5SAndroid Build Coastguard Worker const GLuint baseLevel = mState.getEffectiveBaseLevel();
2192*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = mState.getMipmapMaxLevel();
2193*8975f5c5SAndroid Build Coastguard Worker // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap
2194*8975f5c5SAndroid Build Coastguard Worker // levels.
2195*8975f5c5SAndroid Build Coastguard Worker for (int faceIndex = 0; faceIndex < static_cast<int>(gl::kCubeFaceCount); faceIndex++)
2196*8975f5c5SAndroid Build Coastguard Worker {
2197*8975f5c5SAndroid Build Coastguard Worker for (GLuint level = baseLevel + 1; level <= maxLevel; level++)
2198*8975f5c5SAndroid Build Coastguard Worker {
2199*8975f5c5SAndroid Build Coastguard Worker int faceLevelSize =
2200*8975f5c5SAndroid Build Coastguard Worker (std::max(mImageArray[faceIndex][baseLevel]->getWidth() >> (level - baseLevel), 1));
2201*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, faceIndex, level,
2202*8975f5c5SAndroid Build Coastguard Worker mImageArray[faceIndex][baseLevel]->getInternalFormat(),
2203*8975f5c5SAndroid Build Coastguard Worker gl::Extents(faceLevelSize, faceLevelSize, 1), false));
2204*8975f5c5SAndroid Build Coastguard Worker }
2205*8975f5c5SAndroid Build Coastguard Worker }
2206*8975f5c5SAndroid Build Coastguard Worker
2207*8975f5c5SAndroid Build Coastguard Worker // We should be mip-complete now so generate the storage.
2208*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget()));
2209*8975f5c5SAndroid Build Coastguard Worker
2210*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2211*8975f5c5SAndroid Build Coastguard Worker }
2212*8975f5c5SAndroid Build Coastguard Worker
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)2213*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::getRenderTarget(const gl::Context *context,
2214*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2215*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
2216*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D **outRT)
2217*8975f5c5SAndroid Build Coastguard Worker {
2218*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::IsCubeMapFaceTarget(index.getTarget()));
2219*8975f5c5SAndroid Build Coastguard Worker
2220*8975f5c5SAndroid Build Coastguard Worker // ensure the underlying texture is created
2221*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
2222*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageFaceLevel(context, index.cubeMapFaceIndex(), index.getLevelIndex()));
2223*8975f5c5SAndroid Build Coastguard Worker
2224*8975f5c5SAndroid Build Coastguard Worker return mTexStorage->getRenderTarget(context, index, samples, outRT);
2225*8975f5c5SAndroid Build Coastguard Worker }
2226*8975f5c5SAndroid Build Coastguard Worker
initializeStorage(const gl::Context * context,BindFlags bindFlags)2227*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::initializeStorage(const gl::Context *context, BindFlags bindFlags)
2228*8975f5c5SAndroid Build Coastguard Worker {
2229*8975f5c5SAndroid Build Coastguard Worker // Only initialize the first time this texture is used as a render target or shader resource
2230*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
2231*8975f5c5SAndroid Build Coastguard Worker {
2232*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2233*8975f5c5SAndroid Build Coastguard Worker }
2234*8975f5c5SAndroid Build Coastguard Worker
2235*8975f5c5SAndroid Build Coastguard Worker // do not attempt to create storage for nonexistant data
2236*8975f5c5SAndroid Build Coastguard Worker if (!isFaceLevelComplete(0, getBaseLevel()))
2237*8975f5c5SAndroid Build Coastguard Worker {
2238*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2239*8975f5c5SAndroid Build Coastguard Worker }
2240*8975f5c5SAndroid Build Coastguard Worker
2241*8975f5c5SAndroid Build Coastguard Worker bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage());
2242*8975f5c5SAndroid Build Coastguard Worker
2243*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage;
2244*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage));
2245*8975f5c5SAndroid Build Coastguard Worker
2246*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
2247*8975f5c5SAndroid Build Coastguard Worker storage.release();
2248*8975f5c5SAndroid Build Coastguard Worker
2249*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
2250*8975f5c5SAndroid Build Coastguard Worker
2251*8975f5c5SAndroid Build Coastguard Worker // flush image data to the storage
2252*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
2253*8975f5c5SAndroid Build Coastguard Worker
2254*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2255*8975f5c5SAndroid Build Coastguard Worker }
2256*8975f5c5SAndroid Build Coastguard Worker
createCompleteStorage(const gl::Context * context,BindFlags bindFlags,TexStoragePointer * outStorage) const2257*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::createCompleteStorage(const gl::Context *context,
2258*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags,
2259*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer *outStorage) const
2260*8975f5c5SAndroid Build Coastguard Worker {
2261*8975f5c5SAndroid Build Coastguard Worker GLsizei size = getLevelZeroWidth();
2262*8975f5c5SAndroid Build Coastguard Worker
2263*8975f5c5SAndroid Build Coastguard Worker ASSERT(size > 0);
2264*8975f5c5SAndroid Build Coastguard Worker
2265*8975f5c5SAndroid Build Coastguard Worker // use existing storage level count, when previously specified by TexStorage*D
2266*8975f5c5SAndroid Build Coastguard Worker GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
2267*8975f5c5SAndroid Build Coastguard Worker
2268*8975f5c5SAndroid Build Coastguard Worker bool hintLevelZeroOnly = false;
2269*8975f5c5SAndroid Build Coastguard Worker if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
2270*8975f5c5SAndroid Build Coastguard Worker {
2271*8975f5c5SAndroid Build Coastguard Worker // If any of the CPU images (levels >= 1) are dirty, then the textureStorageEXT should use
2272*8975f5c5SAndroid Build Coastguard Worker // the mipped texture to begin with. Otherwise, it should use the level-zero-only texture.
2273*8975f5c5SAndroid Build Coastguard Worker hintLevelZeroOnly = true;
2274*8975f5c5SAndroid Build Coastguard Worker for (int faceIndex = 0;
2275*8975f5c5SAndroid Build Coastguard Worker faceIndex < static_cast<int>(gl::kCubeFaceCount) && hintLevelZeroOnly; faceIndex++)
2276*8975f5c5SAndroid Build Coastguard Worker {
2277*8975f5c5SAndroid Build Coastguard Worker for (int level = 1; level < levels && hintLevelZeroOnly; level++)
2278*8975f5c5SAndroid Build Coastguard Worker {
2279*8975f5c5SAndroid Build Coastguard Worker hintLevelZeroOnly = !(mImageArray[faceIndex][level]->isDirty() &&
2280*8975f5c5SAndroid Build Coastguard Worker isFaceLevelComplete(faceIndex, level));
2281*8975f5c5SAndroid Build Coastguard Worker }
2282*8975f5c5SAndroid Build Coastguard Worker }
2283*8975f5c5SAndroid Build Coastguard Worker }
2284*8975f5c5SAndroid Build Coastguard Worker
2285*8975f5c5SAndroid Build Coastguard Worker // TODO (geofflang): detect if storage creation succeeded
2286*8975f5c5SAndroid Build Coastguard Worker *outStorage = {
2287*8975f5c5SAndroid Build Coastguard Worker mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), bindFlags, size, levels,
2288*8975f5c5SAndroid Build Coastguard Worker hintLevelZeroOnly, mState.getLabel()),
2289*8975f5c5SAndroid Build Coastguard Worker context};
2290*8975f5c5SAndroid Build Coastguard Worker
2291*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2292*8975f5c5SAndroid Build Coastguard Worker }
2293*8975f5c5SAndroid Build Coastguard Worker
setCompleteTexStorage(const gl::Context * context,TextureStorage * newCompleteTexStorage)2294*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::setCompleteTexStorage(const gl::Context *context,
2295*8975f5c5SAndroid Build Coastguard Worker TextureStorage *newCompleteTexStorage)
2296*8975f5c5SAndroid Build Coastguard Worker {
2297*8975f5c5SAndroid Build Coastguard Worker if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
2298*8975f5c5SAndroid Build Coastguard Worker {
2299*8975f5c5SAndroid Build Coastguard Worker for (int faceIndex = 0; faceIndex < static_cast<int>(gl::kCubeFaceCount); faceIndex++)
2300*8975f5c5SAndroid Build Coastguard Worker {
2301*8975f5c5SAndroid Build Coastguard Worker for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
2302*8975f5c5SAndroid Build Coastguard Worker {
2303*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageArray[faceIndex][level]->setManagedSurfaceCube(
2304*8975f5c5SAndroid Build Coastguard Worker context, newCompleteTexStorage, faceIndex, level));
2305*8975f5c5SAndroid Build Coastguard Worker }
2306*8975f5c5SAndroid Build Coastguard Worker }
2307*8975f5c5SAndroid Build Coastguard Worker }
2308*8975f5c5SAndroid Build Coastguard Worker
2309*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask copyImageMask;
2310*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set();
2311*8975f5c5SAndroid Build Coastguard Worker
2312*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, copyImageMask));
2313*8975f5c5SAndroid Build Coastguard Worker mTexStorage = newCompleteTexStorage;
2314*8975f5c5SAndroid Build Coastguard Worker mTexStorageObserverBinding.bind(mTexStorage);
2315*8975f5c5SAndroid Build Coastguard Worker
2316*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
2317*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2318*8975f5c5SAndroid Build Coastguard Worker }
2319*8975f5c5SAndroid Build Coastguard Worker
updateStorage(const gl::Context * context)2320*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::updateStorage(const gl::Context *context)
2321*8975f5c5SAndroid Build Coastguard Worker {
2322*8975f5c5SAndroid Build Coastguard Worker if (!mDirtyImages)
2323*8975f5c5SAndroid Build Coastguard Worker {
2324*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2325*8975f5c5SAndroid Build Coastguard Worker }
2326*8975f5c5SAndroid Build Coastguard Worker
2327*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage != nullptr);
2328*8975f5c5SAndroid Build Coastguard Worker GLint storageLevels = mTexStorage->getLevelCount();
2329*8975f5c5SAndroid Build Coastguard Worker for (int face = 0; face < static_cast<int>(gl::kCubeFaceCount); face++)
2330*8975f5c5SAndroid Build Coastguard Worker {
2331*8975f5c5SAndroid Build Coastguard Worker for (int level = 0; level < storageLevels; level++)
2332*8975f5c5SAndroid Build Coastguard Worker {
2333*8975f5c5SAndroid Build Coastguard Worker if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
2334*8975f5c5SAndroid Build Coastguard Worker {
2335*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageFaceLevel(context, face, level));
2336*8975f5c5SAndroid Build Coastguard Worker }
2337*8975f5c5SAndroid Build Coastguard Worker }
2338*8975f5c5SAndroid Build Coastguard Worker }
2339*8975f5c5SAndroid Build Coastguard Worker
2340*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = false;
2341*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2342*8975f5c5SAndroid Build Coastguard Worker }
2343*8975f5c5SAndroid Build Coastguard Worker
isValidFaceLevel(int faceIndex,int level) const2344*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
2345*8975f5c5SAndroid Build Coastguard Worker {
2346*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
2347*8975f5c5SAndroid Build Coastguard Worker }
2348*8975f5c5SAndroid Build Coastguard Worker
isFaceLevelComplete(int faceIndex,int level) const2349*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
2350*8975f5c5SAndroid Build Coastguard Worker {
2351*8975f5c5SAndroid Build Coastguard Worker if (getBaseLevel() >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2352*8975f5c5SAndroid Build Coastguard Worker {
2353*8975f5c5SAndroid Build Coastguard Worker return false;
2354*8975f5c5SAndroid Build Coastguard Worker }
2355*8975f5c5SAndroid Build Coastguard Worker ASSERT(level >= 0 && static_cast<size_t>(faceIndex) < gl::kCubeFaceCount &&
2356*8975f5c5SAndroid Build Coastguard Worker level < static_cast<int>(mImageArray[faceIndex].size()) &&
2357*8975f5c5SAndroid Build Coastguard Worker mImageArray[faceIndex][level] != nullptr);
2358*8975f5c5SAndroid Build Coastguard Worker
2359*8975f5c5SAndroid Build Coastguard Worker if (isImmutable())
2360*8975f5c5SAndroid Build Coastguard Worker {
2361*8975f5c5SAndroid Build Coastguard Worker return true;
2362*8975f5c5SAndroid Build Coastguard Worker }
2363*8975f5c5SAndroid Build Coastguard Worker
2364*8975f5c5SAndroid Build Coastguard Worker int levelZeroSize = getLevelZeroWidth();
2365*8975f5c5SAndroid Build Coastguard Worker
2366*8975f5c5SAndroid Build Coastguard Worker if (levelZeroSize <= 0)
2367*8975f5c5SAndroid Build Coastguard Worker {
2368*8975f5c5SAndroid Build Coastguard Worker return false;
2369*8975f5c5SAndroid Build Coastguard Worker }
2370*8975f5c5SAndroid Build Coastguard Worker
2371*8975f5c5SAndroid Build Coastguard Worker // Check that non-zero levels are consistent with the base level.
2372*8975f5c5SAndroid Build Coastguard Worker const ImageD3D *faceLevelImage = mImageArray[faceIndex][level].get();
2373*8975f5c5SAndroid Build Coastguard Worker
2374*8975f5c5SAndroid Build Coastguard Worker if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
2375*8975f5c5SAndroid Build Coastguard Worker {
2376*8975f5c5SAndroid Build Coastguard Worker return false;
2377*8975f5c5SAndroid Build Coastguard Worker }
2378*8975f5c5SAndroid Build Coastguard Worker
2379*8975f5c5SAndroid Build Coastguard Worker if (faceLevelImage->getWidth() != std::max(1, levelZeroSize >> level))
2380*8975f5c5SAndroid Build Coastguard Worker {
2381*8975f5c5SAndroid Build Coastguard Worker return false;
2382*8975f5c5SAndroid Build Coastguard Worker }
2383*8975f5c5SAndroid Build Coastguard Worker
2384*8975f5c5SAndroid Build Coastguard Worker return true;
2385*8975f5c5SAndroid Build Coastguard Worker }
2386*8975f5c5SAndroid Build Coastguard Worker
isImageComplete(const gl::ImageIndex & index) const2387*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Cube::isImageComplete(const gl::ImageIndex &index) const
2388*8975f5c5SAndroid Build Coastguard Worker {
2389*8975f5c5SAndroid Build Coastguard Worker return isFaceLevelComplete(index.cubeMapFaceIndex(), index.getLevelIndex());
2390*8975f5c5SAndroid Build Coastguard Worker }
2391*8975f5c5SAndroid Build Coastguard Worker
updateStorageFaceLevel(const gl::Context * context,int faceIndex,int level)2392*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::updateStorageFaceLevel(const gl::Context *context,
2393*8975f5c5SAndroid Build Coastguard Worker int faceIndex,
2394*8975f5c5SAndroid Build Coastguard Worker int level)
2395*8975f5c5SAndroid Build Coastguard Worker {
2396*8975f5c5SAndroid Build Coastguard Worker ASSERT(level >= 0 && static_cast<size_t>(faceIndex) < gl::kCubeFaceCount &&
2397*8975f5c5SAndroid Build Coastguard Worker level < static_cast<int>(mImageArray[faceIndex].size()) &&
2398*8975f5c5SAndroid Build Coastguard Worker mImageArray[faceIndex][level] != nullptr);
2399*8975f5c5SAndroid Build Coastguard Worker ImageD3D *image = mImageArray[faceIndex][level].get();
2400*8975f5c5SAndroid Build Coastguard Worker
2401*8975f5c5SAndroid Build Coastguard Worker if (image->isDirty())
2402*8975f5c5SAndroid Build Coastguard Worker {
2403*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget faceTarget = gl::CubeFaceIndexToTextureTarget(faceIndex);
2404*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex index = gl::ImageIndex::MakeCubeMapFace(faceTarget, level);
2405*8975f5c5SAndroid Build Coastguard Worker gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1);
2406*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, region));
2407*8975f5c5SAndroid Build Coastguard Worker }
2408*8975f5c5SAndroid Build Coastguard Worker
2409*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2410*8975f5c5SAndroid Build Coastguard Worker }
2411*8975f5c5SAndroid Build Coastguard Worker
redefineImage(const gl::Context * context,int faceIndex,GLint level,GLenum internalformat,const gl::Extents & size,bool forceRelease)2412*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Cube::redefineImage(const gl::Context *context,
2413*8975f5c5SAndroid Build Coastguard Worker int faceIndex,
2414*8975f5c5SAndroid Build Coastguard Worker GLint level,
2415*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
2416*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
2417*8975f5c5SAndroid Build Coastguard Worker bool forceRelease)
2418*8975f5c5SAndroid Build Coastguard Worker {
2419*8975f5c5SAndroid Build Coastguard Worker // If there currently is a corresponding storage texture image, it has these parameters
2420*8975f5c5SAndroid Build Coastguard Worker const int storageWidth = std::max(1, getLevelZeroWidth() >> level);
2421*8975f5c5SAndroid Build Coastguard Worker const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
2422*8975f5c5SAndroid Build Coastguard Worker const GLenum storageFormat = getBaseLevelInternalFormat();
2423*8975f5c5SAndroid Build Coastguard Worker
2424*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
2425*8975f5c5SAndroid Build Coastguard Worker {
2426*8975f5c5SAndroid Build Coastguard Worker const int storageLevels = mTexStorage->getLevelCount();
2427*8975f5c5SAndroid Build Coastguard Worker
2428*8975f5c5SAndroid Build Coastguard Worker if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
2429*8975f5c5SAndroid Build Coastguard Worker size.height != storageHeight ||
2430*8975f5c5SAndroid Build Coastguard Worker internalformat != storageFormat) // Discard mismatched storage
2431*8975f5c5SAndroid Build Coastguard Worker {
2432*8975f5c5SAndroid Build Coastguard Worker markAllImagesDirty();
2433*8975f5c5SAndroid Build Coastguard Worker
2434*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask copyImageMask;
2435*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set();
2436*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set(level, false);
2437*8975f5c5SAndroid Build Coastguard Worker
2438*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, copyImageMask));
2439*8975f5c5SAndroid Build Coastguard Worker }
2440*8975f5c5SAndroid Build Coastguard Worker }
2441*8975f5c5SAndroid Build Coastguard Worker
2442*8975f5c5SAndroid Build Coastguard Worker mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, internalformat, size,
2443*8975f5c5SAndroid Build Coastguard Worker forceRelease);
2444*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = mDirtyImages || mImageArray[faceIndex][level]->isDirty();
2445*8975f5c5SAndroid Build Coastguard Worker
2446*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2447*8975f5c5SAndroid Build Coastguard Worker }
2448*8975f5c5SAndroid Build Coastguard Worker
imageIterator() const2449*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const
2450*8975f5c5SAndroid Build Coastguard Worker {
2451*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount());
2452*8975f5c5SAndroid Build Coastguard Worker }
2453*8975f5c5SAndroid Build Coastguard Worker
getImageIndex(GLint mip,GLint layer) const2454*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex TextureD3D_Cube::getImageIndex(GLint mip, GLint layer) const
2455*8975f5c5SAndroid Build Coastguard Worker {
2456*8975f5c5SAndroid Build Coastguard Worker // The "layer" of the image index corresponds to the cube face
2457*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndex::MakeCubeMapFace(gl::CubeFaceIndexToTextureTarget(layer), mip);
2458*8975f5c5SAndroid Build Coastguard Worker }
2459*8975f5c5SAndroid Build Coastguard Worker
isValidIndex(const gl::ImageIndex & index) const2460*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const
2461*8975f5c5SAndroid Build Coastguard Worker {
2462*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage && index.getType() == gl::TextureType::CubeMap &&
2463*8975f5c5SAndroid Build Coastguard Worker gl::IsCubeMapFaceTarget(index.getTarget()) && index.getLevelIndex() >= 0 &&
2464*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex() < mTexStorage->getLevelCount());
2465*8975f5c5SAndroid Build Coastguard Worker }
2466*8975f5c5SAndroid Build Coastguard Worker
markAllImagesDirty()2467*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_Cube::markAllImagesDirty()
2468*8975f5c5SAndroid Build Coastguard Worker {
2469*8975f5c5SAndroid Build Coastguard Worker for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++)
2470*8975f5c5SAndroid Build Coastguard Worker {
2471*8975f5c5SAndroid Build Coastguard Worker for (size_t dirtyFace = 0; dirtyFace < gl::kCubeFaceCount; dirtyFace++)
2472*8975f5c5SAndroid Build Coastguard Worker {
2473*8975f5c5SAndroid Build Coastguard Worker mImageArray[dirtyFace][dirtyLevel]->markDirty();
2474*8975f5c5SAndroid Build Coastguard Worker }
2475*8975f5c5SAndroid Build Coastguard Worker }
2476*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
2477*8975f5c5SAndroid Build Coastguard Worker }
2478*8975f5c5SAndroid Build Coastguard Worker
TextureD3D_3D(const gl::TextureState & state,RendererD3D * renderer)2479*8975f5c5SAndroid Build Coastguard Worker TextureD3D_3D::TextureD3D_3D(const gl::TextureState &state, RendererD3D *renderer)
2480*8975f5c5SAndroid Build Coastguard Worker : TextureD3D(state, renderer)
2481*8975f5c5SAndroid Build Coastguard Worker {
2482*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
2483*8975f5c5SAndroid Build Coastguard Worker {
2484*8975f5c5SAndroid Build Coastguard Worker mImageArray[i].reset(renderer->createImage());
2485*8975f5c5SAndroid Build Coastguard Worker }
2486*8975f5c5SAndroid Build Coastguard Worker }
2487*8975f5c5SAndroid Build Coastguard Worker
onDestroy(const gl::Context * context)2488*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_3D::onDestroy(const gl::Context *context)
2489*8975f5c5SAndroid Build Coastguard Worker {
2490*8975f5c5SAndroid Build Coastguard Worker // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage
2491*8975f5c5SAndroid Build Coastguard Worker // for some of their data. If TextureStorage is deleted before the Images, then their data will
2492*8975f5c5SAndroid Build Coastguard Worker // be wastefully copied back from the GPU before we delete the Images.
2493*8975f5c5SAndroid Build Coastguard Worker for (auto &image : mImageArray)
2494*8975f5c5SAndroid Build Coastguard Worker {
2495*8975f5c5SAndroid Build Coastguard Worker image.reset();
2496*8975f5c5SAndroid Build Coastguard Worker }
2497*8975f5c5SAndroid Build Coastguard Worker return TextureD3D::onDestroy(context);
2498*8975f5c5SAndroid Build Coastguard Worker }
2499*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D_3D()2500*8975f5c5SAndroid Build Coastguard Worker TextureD3D_3D::~TextureD3D_3D() {}
2501*8975f5c5SAndroid Build Coastguard Worker
getImage(int level,int layer) const2502*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_3D::getImage(int level, int layer) const
2503*8975f5c5SAndroid Build Coastguard Worker {
2504*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2505*8975f5c5SAndroid Build Coastguard Worker ASSERT(layer == 0);
2506*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level].get();
2507*8975f5c5SAndroid Build Coastguard Worker }
2508*8975f5c5SAndroid Build Coastguard Worker
getImage(const gl::ImageIndex & index) const2509*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_3D::getImage(const gl::ImageIndex &index) const
2510*8975f5c5SAndroid Build Coastguard Worker {
2511*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2512*8975f5c5SAndroid Build Coastguard Worker ASSERT(!index.hasLayer());
2513*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getType() == gl::TextureType::_3D);
2514*8975f5c5SAndroid Build Coastguard Worker return mImageArray[index.getLevelIndex()].get();
2515*8975f5c5SAndroid Build Coastguard Worker }
2516*8975f5c5SAndroid Build Coastguard Worker
getLayerCount(int level) const2517*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_3D::getLayerCount(int level) const
2518*8975f5c5SAndroid Build Coastguard Worker {
2519*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2520*8975f5c5SAndroid Build Coastguard Worker return 1;
2521*8975f5c5SAndroid Build Coastguard Worker }
2522*8975f5c5SAndroid Build Coastguard Worker
getWidth(GLint level) const2523*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_3D::getWidth(GLint level) const
2524*8975f5c5SAndroid Build Coastguard Worker {
2525*8975f5c5SAndroid Build Coastguard Worker if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2526*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level]->getWidth();
2527*8975f5c5SAndroid Build Coastguard Worker else
2528*8975f5c5SAndroid Build Coastguard Worker return 0;
2529*8975f5c5SAndroid Build Coastguard Worker }
2530*8975f5c5SAndroid Build Coastguard Worker
getHeight(GLint level) const2531*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_3D::getHeight(GLint level) const
2532*8975f5c5SAndroid Build Coastguard Worker {
2533*8975f5c5SAndroid Build Coastguard Worker if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2534*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level]->getHeight();
2535*8975f5c5SAndroid Build Coastguard Worker else
2536*8975f5c5SAndroid Build Coastguard Worker return 0;
2537*8975f5c5SAndroid Build Coastguard Worker }
2538*8975f5c5SAndroid Build Coastguard Worker
getDepth(GLint level) const2539*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_3D::getDepth(GLint level) const
2540*8975f5c5SAndroid Build Coastguard Worker {
2541*8975f5c5SAndroid Build Coastguard Worker if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2542*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level]->getDepth();
2543*8975f5c5SAndroid Build Coastguard Worker else
2544*8975f5c5SAndroid Build Coastguard Worker return 0;
2545*8975f5c5SAndroid Build Coastguard Worker }
2546*8975f5c5SAndroid Build Coastguard Worker
getInternalFormat(GLint level) const2547*8975f5c5SAndroid Build Coastguard Worker GLenum TextureD3D_3D::getInternalFormat(GLint level) const
2548*8975f5c5SAndroid Build Coastguard Worker {
2549*8975f5c5SAndroid Build Coastguard Worker if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2550*8975f5c5SAndroid Build Coastguard Worker return mImageArray[level]->getInternalFormat();
2551*8975f5c5SAndroid Build Coastguard Worker else
2552*8975f5c5SAndroid Build Coastguard Worker return GL_NONE;
2553*8975f5c5SAndroid Build Coastguard Worker }
2554*8975f5c5SAndroid Build Coastguard Worker
isDepth(GLint level) const2555*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_3D::isDepth(GLint level) const
2556*8975f5c5SAndroid Build Coastguard Worker {
2557*8975f5c5SAndroid Build Coastguard Worker return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
2558*8975f5c5SAndroid Build Coastguard Worker }
2559*8975f5c5SAndroid Build Coastguard Worker
isSRGB(GLint level) const2560*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_3D::isSRGB(GLint level) const
2561*8975f5c5SAndroid Build Coastguard Worker {
2562*8975f5c5SAndroid Build Coastguard Worker return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB;
2563*8975f5c5SAndroid Build Coastguard Worker }
2564*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)2565*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::setEGLImageTarget(const gl::Context *context,
2566*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
2567*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
2568*8975f5c5SAndroid Build Coastguard Worker {
2569*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
2570*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2571*8975f5c5SAndroid Build Coastguard Worker }
2572*8975f5c5SAndroid Build Coastguard Worker
setImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)2573*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::setImage(const gl::Context *context,
2574*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2575*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
2576*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
2577*8975f5c5SAndroid Build Coastguard Worker GLenum format,
2578*8975f5c5SAndroid Build Coastguard Worker GLenum type,
2579*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
2580*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
2581*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
2582*8975f5c5SAndroid Build Coastguard Worker {
2583*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_3D);
2584*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
2585*8975f5c5SAndroid Build Coastguard Worker
2586*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
2587*8975f5c5SAndroid Build Coastguard Worker size, false));
2588*8975f5c5SAndroid Build Coastguard Worker
2589*8975f5c5SAndroid Build Coastguard Worker bool fastUnpacked = false;
2590*8975f5c5SAndroid Build Coastguard Worker
2591*8975f5c5SAndroid Build Coastguard Worker // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
2592*8975f5c5SAndroid Build Coastguard Worker if (isFastUnpackable(unpackBuffer, unpack, internalFormatInfo.sizedInternalFormat) &&
2593*8975f5c5SAndroid Build Coastguard Worker !size.empty() && isLevelComplete(index.getLevelIndex()))
2594*8975f5c5SAndroid Build Coastguard Worker {
2595*8975f5c5SAndroid Build Coastguard Worker // Will try to create RT storage if it does not exist
2596*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *destRenderTarget = nullptr;
2597*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget));
2598*8975f5c5SAndroid Build Coastguard Worker
2599*8975f5c5SAndroid Build Coastguard Worker gl::Box destArea(0, 0, 0, getWidth(index.getLevelIndex()), getHeight(index.getLevelIndex()),
2600*8975f5c5SAndroid Build Coastguard Worker getDepth(index.getLevelIndex()));
2601*8975f5c5SAndroid Build Coastguard Worker
2602*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(fastUnpackPixels(context, unpack, unpackBuffer, pixels, destArea,
2603*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.sizedInternalFormat, type, destRenderTarget));
2604*8975f5c5SAndroid Build Coastguard Worker
2605*8975f5c5SAndroid Build Coastguard Worker // Ensure we don't overwrite our newly initialized data
2606*8975f5c5SAndroid Build Coastguard Worker mImageArray[index.getLevelIndex()]->markClean();
2607*8975f5c5SAndroid Build Coastguard Worker
2608*8975f5c5SAndroid Build Coastguard Worker fastUnpacked = true;
2609*8975f5c5SAndroid Build Coastguard Worker }
2610*8975f5c5SAndroid Build Coastguard Worker
2611*8975f5c5SAndroid Build Coastguard Worker if (!fastUnpacked)
2612*8975f5c5SAndroid Build Coastguard Worker {
2613*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0));
2614*8975f5c5SAndroid Build Coastguard Worker }
2615*8975f5c5SAndroid Build Coastguard Worker
2616*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2617*8975f5c5SAndroid Build Coastguard Worker }
2618*8975f5c5SAndroid Build Coastguard Worker
setSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)2619*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::setSubImage(const gl::Context *context,
2620*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2621*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
2622*8975f5c5SAndroid Build Coastguard Worker GLenum format,
2623*8975f5c5SAndroid Build Coastguard Worker GLenum type,
2624*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
2625*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
2626*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
2627*8975f5c5SAndroid Build Coastguard Worker {
2628*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_3D);
2629*8975f5c5SAndroid Build Coastguard Worker
2630*8975f5c5SAndroid Build Coastguard Worker // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
2631*8975f5c5SAndroid Build Coastguard Worker GLenum mipFormat = getInternalFormat(index.getLevelIndex());
2632*8975f5c5SAndroid Build Coastguard Worker if (isFastUnpackable(unpackBuffer, unpack, mipFormat) && isLevelComplete(index.getLevelIndex()))
2633*8975f5c5SAndroid Build Coastguard Worker {
2634*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *destRenderTarget = nullptr;
2635*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget));
2636*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mImageArray[index.getLevelIndex()]->isDirty());
2637*8975f5c5SAndroid Build Coastguard Worker
2638*8975f5c5SAndroid Build Coastguard Worker return fastUnpackPixels(context, unpack, unpackBuffer, pixels, area, mipFormat, type,
2639*8975f5c5SAndroid Build Coastguard Worker destRenderTarget);
2640*8975f5c5SAndroid Build Coastguard Worker }
2641*8975f5c5SAndroid Build Coastguard Worker else
2642*8975f5c5SAndroid Build Coastguard Worker {
2643*8975f5c5SAndroid Build Coastguard Worker return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer,
2644*8975f5c5SAndroid Build Coastguard Worker pixels, 0);
2645*8975f5c5SAndroid Build Coastguard Worker }
2646*8975f5c5SAndroid Build Coastguard Worker }
2647*8975f5c5SAndroid Build Coastguard Worker
setCompressedImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)2648*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::setCompressedImage(const gl::Context *context,
2649*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2650*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
2651*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
2652*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
2653*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
2654*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
2655*8975f5c5SAndroid Build Coastguard Worker {
2656*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_3D);
2657*8975f5c5SAndroid Build Coastguard Worker
2658*8975f5c5SAndroid Build Coastguard Worker // compressed formats don't have separate sized internal formats-- we can just use the
2659*8975f5c5SAndroid Build Coastguard Worker // compressed format directly
2660*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false));
2661*8975f5c5SAndroid Build Coastguard Worker
2662*8975f5c5SAndroid Build Coastguard Worker return setCompressedImageImpl(context, index, unpack, pixels, 0);
2663*8975f5c5SAndroid Build Coastguard Worker }
2664*8975f5c5SAndroid Build Coastguard Worker
setCompressedSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)2665*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::setCompressedSubImage(const gl::Context *context,
2666*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2667*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
2668*8975f5c5SAndroid Build Coastguard Worker GLenum format,
2669*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
2670*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
2671*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
2672*8975f5c5SAndroid Build Coastguard Worker {
2673*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_3D);
2674*8975f5c5SAndroid Build Coastguard Worker
2675*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
2676*8975f5c5SAndroid Build Coastguard Worker return commitRegion(context, index, area);
2677*8975f5c5SAndroid Build Coastguard Worker }
2678*8975f5c5SAndroid Build Coastguard Worker
copyImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Rectangle & sourceArea,GLenum internalFormat,gl::Framebuffer * source)2679*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::copyImage(const gl::Context *context,
2680*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2681*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
2682*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
2683*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
2684*8975f5c5SAndroid Build Coastguard Worker {
2685*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
2686*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2687*8975f5c5SAndroid Build Coastguard Worker }
2688*8975f5c5SAndroid Build Coastguard Worker
copySubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,const gl::Rectangle & sourceArea,gl::Framebuffer * source)2689*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::copySubImage(const gl::Context *context,
2690*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2691*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
2692*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
2693*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
2694*8975f5c5SAndroid Build Coastguard Worker {
2695*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_3D);
2696*8975f5c5SAndroid Build Coastguard Worker
2697*8975f5c5SAndroid Build Coastguard Worker gl::Extents fbSize = source->getReadColorAttachment()->getSize();
2698*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedSourceArea;
2699*8975f5c5SAndroid Build Coastguard Worker if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
2700*8975f5c5SAndroid Build Coastguard Worker &clippedSourceArea))
2701*8975f5c5SAndroid Build Coastguard Worker {
2702*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2703*8975f5c5SAndroid Build Coastguard Worker }
2704*8975f5c5SAndroid Build Coastguard Worker const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x,
2705*8975f5c5SAndroid Build Coastguard Worker destOffset.y + clippedSourceArea.y - sourceArea.y,
2706*8975f5c5SAndroid Build Coastguard Worker destOffset.z);
2707*8975f5c5SAndroid Build Coastguard Worker
2708*8975f5c5SAndroid Build Coastguard Worker // Currently, copying directly to the storage is not possible because it's not possible to
2709*8975f5c5SAndroid Build Coastguard Worker // create an SRV from a single layer of a 3D texture. Instead, make sure the image is up to
2710*8975f5c5SAndroid Build Coastguard Worker // date before the copy and then copy back to the storage afterwards if needed.
2711*8975f5c5SAndroid Build Coastguard Worker // TODO: Investigate 3D blits in D3D11.
2712*8975f5c5SAndroid Build Coastguard Worker
2713*8975f5c5SAndroid Build Coastguard Worker bool syncTexStorage = mTexStorage && isLevelComplete(index.getLevelIndex());
2714*8975f5c5SAndroid Build Coastguard Worker if (syncTexStorage)
2715*8975f5c5SAndroid Build Coastguard Worker {
2716*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
2717*8975f5c5SAndroid Build Coastguard Worker mImageArray[index.getLevelIndex()]->copyFromTexStorage(context, index, mTexStorage));
2718*8975f5c5SAndroid Build Coastguard Worker }
2719*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, clippedDestOffset,
2720*8975f5c5SAndroid Build Coastguard Worker clippedSourceArea, source));
2721*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
2722*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
2723*8975f5c5SAndroid Build Coastguard Worker
2724*8975f5c5SAndroid Build Coastguard Worker if (syncTexStorage)
2725*8975f5c5SAndroid Build Coastguard Worker {
2726*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
2727*8975f5c5SAndroid Build Coastguard Worker }
2728*8975f5c5SAndroid Build Coastguard Worker
2729*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2730*8975f5c5SAndroid Build Coastguard Worker }
2731*8975f5c5SAndroid Build Coastguard Worker
copyTexture(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,GLenum type,GLint sourceLevel,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)2732*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::copyTexture(const gl::Context *context,
2733*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2734*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
2735*8975f5c5SAndroid Build Coastguard Worker GLenum type,
2736*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
2737*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
2738*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
2739*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
2740*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
2741*8975f5c5SAndroid Build Coastguard Worker {
2742*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_3D);
2743*8975f5c5SAndroid Build Coastguard Worker
2744*8975f5c5SAndroid Build Coastguard Worker gl::TextureType sourceType = source->getType();
2745*8975f5c5SAndroid Build Coastguard Worker
2746*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
2747*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(
2748*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
2749*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
2750*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getDepth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)));
2751*8975f5c5SAndroid Build Coastguard Worker
2752*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
2753*8975f5c5SAndroid Build Coastguard Worker size, false));
2754*8975f5c5SAndroid Build Coastguard Worker
2755*8975f5c5SAndroid Build Coastguard Worker gl::Box sourceBox(0, 0, 0, size.width, size.height, size.depth);
2756*8975f5c5SAndroid Build Coastguard Worker gl::Offset destOffset(0, 0, 0);
2757*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex destIndex = gl::ImageIndex::Make3D(static_cast<GLint>(index.getLevelIndex()));
2758*8975f5c5SAndroid Build Coastguard Worker
2759*8975f5c5SAndroid Build Coastguard Worker if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(destIndex))
2760*8975f5c5SAndroid Build Coastguard Worker {
2761*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
2762*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidLevel(index.getLevelIndex()));
2763*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
2764*8975f5c5SAndroid Build Coastguard Worker
2765*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_3D,
2766*8975f5c5SAndroid Build Coastguard Worker sourceBox, internalFormatInfo.format,
2767*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type, destOffset, mTexStorage,
2768*8975f5c5SAndroid Build Coastguard Worker index.getTarget(), index.getLevelIndex(), unpackFlipY,
2769*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
2770*8975f5c5SAndroid Build Coastguard Worker }
2771*8975f5c5SAndroid Build Coastguard Worker else
2772*8975f5c5SAndroid Build Coastguard Worker {
2773*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex sourceIndex = gl::ImageIndex::Make3D(sourceLevel);
2774*8975f5c5SAndroid Build Coastguard Worker ImageD3D *sourceImage = nullptr;
2775*8975f5c5SAndroid Build Coastguard Worker ImageD3D *destImage = nullptr;
2776*8975f5c5SAndroid Build Coastguard Worker TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
2777*8975f5c5SAndroid Build Coastguard Worker
2778*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImageAndSyncFromStorage(context, destIndex, &destImage));
2779*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceIndex, &sourceImage));
2780*8975f5c5SAndroid Build Coastguard Worker
2781*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
2782*8975f5c5SAndroid Build Coastguard Worker unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
2783*8975f5c5SAndroid Build Coastguard Worker
2784*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
2785*8975f5c5SAndroid Build Coastguard Worker
2786*8975f5c5SAndroid Build Coastguard Worker gl::Box destRegion(0, 0, 0, sourceBox.width, sourceBox.height, sourceBox.depth);
2787*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, destIndex, destRegion));
2788*8975f5c5SAndroid Build Coastguard Worker }
2789*8975f5c5SAndroid Build Coastguard Worker
2790*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2791*8975f5c5SAndroid Build Coastguard Worker }
copySubTexture(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,GLint sourceLevel,const gl::Box & sourceBox,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)2792*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::copySubTexture(const gl::Context *context,
2793*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2794*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
2795*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
2796*8975f5c5SAndroid Build Coastguard Worker const gl::Box &sourceBox,
2797*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
2798*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
2799*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
2800*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
2801*8975f5c5SAndroid Build Coastguard Worker {
2802*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_3D);
2803*8975f5c5SAndroid Build Coastguard Worker
2804*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex destIndex = gl::ImageIndex::Make3D(static_cast<GLint>(index.getLevelIndex()));
2805*8975f5c5SAndroid Build Coastguard Worker
2806*8975f5c5SAndroid Build Coastguard Worker if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(destIndex))
2807*8975f5c5SAndroid Build Coastguard Worker {
2808*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
2809*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidLevel(index.getLevelIndex()));
2810*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
2811*8975f5c5SAndroid Build Coastguard Worker
2812*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
2813*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex()));
2814*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_3D,
2815*8975f5c5SAndroid Build Coastguard Worker sourceBox, internalFormatInfo.format,
2816*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type, destOffset, mTexStorage,
2817*8975f5c5SAndroid Build Coastguard Worker index.getTarget(), index.getLevelIndex(), unpackFlipY,
2818*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
2819*8975f5c5SAndroid Build Coastguard Worker }
2820*8975f5c5SAndroid Build Coastguard Worker else
2821*8975f5c5SAndroid Build Coastguard Worker {
2822*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make3D(sourceLevel);
2823*8975f5c5SAndroid Build Coastguard Worker TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
2824*8975f5c5SAndroid Build Coastguard Worker ImageD3D *sourceImage = nullptr;
2825*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
2826*8975f5c5SAndroid Build Coastguard Worker
2827*8975f5c5SAndroid Build Coastguard Worker ImageD3D *destImage = nullptr;
2828*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImageAndSyncFromStorage(context, destIndex, &destImage));
2829*8975f5c5SAndroid Build Coastguard Worker
2830*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
2831*8975f5c5SAndroid Build Coastguard Worker unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
2832*8975f5c5SAndroid Build Coastguard Worker
2833*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
2834*8975f5c5SAndroid Build Coastguard Worker
2835*8975f5c5SAndroid Build Coastguard Worker gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width,
2836*8975f5c5SAndroid Build Coastguard Worker sourceBox.height, sourceBox.depth);
2837*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, destIndex, destRegion));
2838*8975f5c5SAndroid Build Coastguard Worker }
2839*8975f5c5SAndroid Build Coastguard Worker
2840*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2841*8975f5c5SAndroid Build Coastguard Worker }
2842*8975f5c5SAndroid Build Coastguard Worker
setStorage(const gl::Context * context,gl::TextureType type,size_t levels,GLenum internalFormat,const gl::Extents & size)2843*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::setStorage(const gl::Context *context,
2844*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
2845*8975f5c5SAndroid Build Coastguard Worker size_t levels,
2846*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
2847*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size)
2848*8975f5c5SAndroid Build Coastguard Worker {
2849*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == gl::TextureType::_3D);
2850*8975f5c5SAndroid Build Coastguard Worker
2851*8975f5c5SAndroid Build Coastguard Worker for (size_t level = 0; level < levels; level++)
2852*8975f5c5SAndroid Build Coastguard Worker {
2853*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelSize(std::max(1, size.width >> level), std::max(1, size.height >> level),
2854*8975f5c5SAndroid Build Coastguard Worker std::max(1, size.depth >> level));
2855*8975f5c5SAndroid Build Coastguard Worker mImageArray[level]->redefine(gl::TextureType::_3D, internalFormat, levelSize, true);
2856*8975f5c5SAndroid Build Coastguard Worker }
2857*8975f5c5SAndroid Build Coastguard Worker
2858*8975f5c5SAndroid Build Coastguard Worker for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
2859*8975f5c5SAndroid Build Coastguard Worker {
2860*8975f5c5SAndroid Build Coastguard Worker mImageArray[level]->redefine(gl::TextureType::_3D, GL_NONE, gl::Extents(0, 0, 0), true);
2861*8975f5c5SAndroid Build Coastguard Worker }
2862*8975f5c5SAndroid Build Coastguard Worker
2863*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Verify storage creation had no errors
2864*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags;
2865*8975f5c5SAndroid Build Coastguard Worker bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage());
2866*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage = {
2867*8975f5c5SAndroid Build Coastguard Worker mRenderer->createTextureStorage3D(internalFormat, bindFlags, size.width, size.height,
2868*8975f5c5SAndroid Build Coastguard Worker size.depth, static_cast<int>(levels), mState.getLabel()),
2869*8975f5c5SAndroid Build Coastguard Worker context};
2870*8975f5c5SAndroid Build Coastguard Worker
2871*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
2872*8975f5c5SAndroid Build Coastguard Worker storage.release();
2873*8975f5c5SAndroid Build Coastguard Worker
2874*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
2875*8975f5c5SAndroid Build Coastguard Worker
2876*8975f5c5SAndroid Build Coastguard Worker mImmutable = true;
2877*8975f5c5SAndroid Build Coastguard Worker
2878*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2879*8975f5c5SAndroid Build Coastguard Worker }
2880*8975f5c5SAndroid Build Coastguard Worker
bindTexImage(const gl::Context * context,egl::Surface * surface)2881*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::bindTexImage(const gl::Context *context, egl::Surface *surface)
2882*8975f5c5SAndroid Build Coastguard Worker {
2883*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
2884*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2885*8975f5c5SAndroid Build Coastguard Worker }
2886*8975f5c5SAndroid Build Coastguard Worker
releaseTexImage(const gl::Context * context)2887*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::releaseTexImage(const gl::Context *context)
2888*8975f5c5SAndroid Build Coastguard Worker {
2889*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
2890*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2891*8975f5c5SAndroid Build Coastguard Worker }
2892*8975f5c5SAndroid Build Coastguard Worker
initMipmapImages(const gl::Context * context)2893*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::initMipmapImages(const gl::Context *context)
2894*8975f5c5SAndroid Build Coastguard Worker {
2895*8975f5c5SAndroid Build Coastguard Worker const GLuint baseLevel = mState.getEffectiveBaseLevel();
2896*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = mState.getMipmapMaxLevel();
2897*8975f5c5SAndroid Build Coastguard Worker // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap
2898*8975f5c5SAndroid Build Coastguard Worker // levels.
2899*8975f5c5SAndroid Build Coastguard Worker for (GLuint level = baseLevel + 1; level <= maxLevel; level++)
2900*8975f5c5SAndroid Build Coastguard Worker {
2901*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelSize(std::max(getLevelZeroWidth() >> level, 1),
2902*8975f5c5SAndroid Build Coastguard Worker std::max(getLevelZeroHeight() >> level, 1),
2903*8975f5c5SAndroid Build Coastguard Worker std::max(getLevelZeroDepth() >> level, 1));
2904*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, level, getBaseLevelInternalFormat(), levelSize, false));
2905*8975f5c5SAndroid Build Coastguard Worker }
2906*8975f5c5SAndroid Build Coastguard Worker
2907*8975f5c5SAndroid Build Coastguard Worker // We should be mip-complete now so generate the storage.
2908*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget()));
2909*8975f5c5SAndroid Build Coastguard Worker
2910*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2911*8975f5c5SAndroid Build Coastguard Worker }
2912*8975f5c5SAndroid Build Coastguard Worker
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)2913*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::getRenderTarget(const gl::Context *context,
2914*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2915*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
2916*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D **outRT)
2917*8975f5c5SAndroid Build Coastguard Worker {
2918*8975f5c5SAndroid Build Coastguard Worker // ensure the underlying texture is created
2919*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
2920*8975f5c5SAndroid Build Coastguard Worker
2921*8975f5c5SAndroid Build Coastguard Worker if (index.hasLayer())
2922*8975f5c5SAndroid Build Coastguard Worker {
2923*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
2924*8975f5c5SAndroid Build Coastguard Worker }
2925*8975f5c5SAndroid Build Coastguard Worker else
2926*8975f5c5SAndroid Build Coastguard Worker {
2927*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
2928*8975f5c5SAndroid Build Coastguard Worker }
2929*8975f5c5SAndroid Build Coastguard Worker
2930*8975f5c5SAndroid Build Coastguard Worker return mTexStorage->getRenderTarget(context, index, samples, outRT);
2931*8975f5c5SAndroid Build Coastguard Worker }
2932*8975f5c5SAndroid Build Coastguard Worker
initializeStorage(const gl::Context * context,BindFlags bindFlags)2933*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::initializeStorage(const gl::Context *context, BindFlags bindFlags)
2934*8975f5c5SAndroid Build Coastguard Worker {
2935*8975f5c5SAndroid Build Coastguard Worker // Only initialize the first time this texture is used as a render target or shader resource
2936*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
2937*8975f5c5SAndroid Build Coastguard Worker {
2938*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2939*8975f5c5SAndroid Build Coastguard Worker }
2940*8975f5c5SAndroid Build Coastguard Worker
2941*8975f5c5SAndroid Build Coastguard Worker // do not attempt to create storage for nonexistant data
2942*8975f5c5SAndroid Build Coastguard Worker if (!isLevelComplete(getBaseLevel()))
2943*8975f5c5SAndroid Build Coastguard Worker {
2944*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2945*8975f5c5SAndroid Build Coastguard Worker }
2946*8975f5c5SAndroid Build Coastguard Worker
2947*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage;
2948*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage));
2949*8975f5c5SAndroid Build Coastguard Worker
2950*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
2951*8975f5c5SAndroid Build Coastguard Worker storage.release();
2952*8975f5c5SAndroid Build Coastguard Worker
2953*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
2954*8975f5c5SAndroid Build Coastguard Worker
2955*8975f5c5SAndroid Build Coastguard Worker // flush image data to the storage
2956*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
2957*8975f5c5SAndroid Build Coastguard Worker
2958*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2959*8975f5c5SAndroid Build Coastguard Worker }
2960*8975f5c5SAndroid Build Coastguard Worker
createCompleteStorage(const gl::Context * context,BindFlags bindFlags,TexStoragePointer * outStorage) const2961*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::createCompleteStorage(const gl::Context *context,
2962*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags,
2963*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer *outStorage) const
2964*8975f5c5SAndroid Build Coastguard Worker {
2965*8975f5c5SAndroid Build Coastguard Worker GLsizei width = getLevelZeroWidth();
2966*8975f5c5SAndroid Build Coastguard Worker GLsizei height = getLevelZeroHeight();
2967*8975f5c5SAndroid Build Coastguard Worker GLsizei depth = getLevelZeroDepth();
2968*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat = getBaseLevelInternalFormat();
2969*8975f5c5SAndroid Build Coastguard Worker
2970*8975f5c5SAndroid Build Coastguard Worker ASSERT(width > 0 && height > 0 && depth > 0);
2971*8975f5c5SAndroid Build Coastguard Worker
2972*8975f5c5SAndroid Build Coastguard Worker // use existing storage level count, when previously specified by TexStorage*D
2973*8975f5c5SAndroid Build Coastguard Worker GLint levels =
2974*8975f5c5SAndroid Build Coastguard Worker (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth));
2975*8975f5c5SAndroid Build Coastguard Worker
2976*8975f5c5SAndroid Build Coastguard Worker // TODO: Verify creation of the storage succeeded
2977*8975f5c5SAndroid Build Coastguard Worker *outStorage = {mRenderer->createTextureStorage3D(internalFormat, bindFlags, width, height,
2978*8975f5c5SAndroid Build Coastguard Worker depth, levels, mState.getLabel()),
2979*8975f5c5SAndroid Build Coastguard Worker context};
2980*8975f5c5SAndroid Build Coastguard Worker
2981*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2982*8975f5c5SAndroid Build Coastguard Worker }
2983*8975f5c5SAndroid Build Coastguard Worker
setCompleteTexStorage(const gl::Context * context,TextureStorage * newCompleteTexStorage)2984*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::setCompleteTexStorage(const gl::Context *context,
2985*8975f5c5SAndroid Build Coastguard Worker TextureStorage *newCompleteTexStorage)
2986*8975f5c5SAndroid Build Coastguard Worker {
2987*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask copyImageMask;
2988*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set();
2989*8975f5c5SAndroid Build Coastguard Worker
2990*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, copyImageMask));
2991*8975f5c5SAndroid Build Coastguard Worker mTexStorage = newCompleteTexStorage;
2992*8975f5c5SAndroid Build Coastguard Worker mTexStorageObserverBinding.bind(mTexStorage);
2993*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
2994*8975f5c5SAndroid Build Coastguard Worker
2995*8975f5c5SAndroid Build Coastguard Worker // We do not support managed 3D storage, as that is D3D9/ES2-only
2996*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mTexStorage->isManaged());
2997*8975f5c5SAndroid Build Coastguard Worker
2998*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2999*8975f5c5SAndroid Build Coastguard Worker }
3000*8975f5c5SAndroid Build Coastguard Worker
updateStorage(const gl::Context * context)3001*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::updateStorage(const gl::Context *context)
3002*8975f5c5SAndroid Build Coastguard Worker {
3003*8975f5c5SAndroid Build Coastguard Worker if (!mDirtyImages)
3004*8975f5c5SAndroid Build Coastguard Worker {
3005*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3006*8975f5c5SAndroid Build Coastguard Worker }
3007*8975f5c5SAndroid Build Coastguard Worker
3008*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage != nullptr);
3009*8975f5c5SAndroid Build Coastguard Worker GLint storageLevels = mTexStorage->getLevelCount();
3010*8975f5c5SAndroid Build Coastguard Worker for (int level = 0; level < storageLevels; level++)
3011*8975f5c5SAndroid Build Coastguard Worker {
3012*8975f5c5SAndroid Build Coastguard Worker if (mImageArray[level]->isDirty() && isLevelComplete(level))
3013*8975f5c5SAndroid Build Coastguard Worker {
3014*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, level));
3015*8975f5c5SAndroid Build Coastguard Worker }
3016*8975f5c5SAndroid Build Coastguard Worker }
3017*8975f5c5SAndroid Build Coastguard Worker
3018*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = false;
3019*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3020*8975f5c5SAndroid Build Coastguard Worker }
3021*8975f5c5SAndroid Build Coastguard Worker
isValidLevel(int level) const3022*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_3D::isValidLevel(int level) const
3023*8975f5c5SAndroid Build Coastguard Worker {
3024*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
3025*8975f5c5SAndroid Build Coastguard Worker }
3026*8975f5c5SAndroid Build Coastguard Worker
isLevelComplete(int level) const3027*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_3D::isLevelComplete(int level) const
3028*8975f5c5SAndroid Build Coastguard Worker {
3029*8975f5c5SAndroid Build Coastguard Worker ASSERT(level >= 0 && level < static_cast<int>(mImageArray.size()) &&
3030*8975f5c5SAndroid Build Coastguard Worker mImageArray[level] != nullptr);
3031*8975f5c5SAndroid Build Coastguard Worker
3032*8975f5c5SAndroid Build Coastguard Worker if (isImmutable())
3033*8975f5c5SAndroid Build Coastguard Worker {
3034*8975f5c5SAndroid Build Coastguard Worker return true;
3035*8975f5c5SAndroid Build Coastguard Worker }
3036*8975f5c5SAndroid Build Coastguard Worker
3037*8975f5c5SAndroid Build Coastguard Worker GLsizei width = getLevelZeroWidth();
3038*8975f5c5SAndroid Build Coastguard Worker GLsizei height = getLevelZeroHeight();
3039*8975f5c5SAndroid Build Coastguard Worker GLsizei depth = getLevelZeroDepth();
3040*8975f5c5SAndroid Build Coastguard Worker
3041*8975f5c5SAndroid Build Coastguard Worker if (width <= 0 || height <= 0 || depth <= 0)
3042*8975f5c5SAndroid Build Coastguard Worker {
3043*8975f5c5SAndroid Build Coastguard Worker return false;
3044*8975f5c5SAndroid Build Coastguard Worker }
3045*8975f5c5SAndroid Build Coastguard Worker
3046*8975f5c5SAndroid Build Coastguard Worker if (level == static_cast<int>(getBaseLevel()))
3047*8975f5c5SAndroid Build Coastguard Worker {
3048*8975f5c5SAndroid Build Coastguard Worker return true;
3049*8975f5c5SAndroid Build Coastguard Worker }
3050*8975f5c5SAndroid Build Coastguard Worker
3051*8975f5c5SAndroid Build Coastguard Worker ImageD3D *levelImage = mImageArray[level].get();
3052*8975f5c5SAndroid Build Coastguard Worker
3053*8975f5c5SAndroid Build Coastguard Worker if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
3054*8975f5c5SAndroid Build Coastguard Worker {
3055*8975f5c5SAndroid Build Coastguard Worker return false;
3056*8975f5c5SAndroid Build Coastguard Worker }
3057*8975f5c5SAndroid Build Coastguard Worker
3058*8975f5c5SAndroid Build Coastguard Worker if (levelImage->getWidth() != std::max(1, width >> level))
3059*8975f5c5SAndroid Build Coastguard Worker {
3060*8975f5c5SAndroid Build Coastguard Worker return false;
3061*8975f5c5SAndroid Build Coastguard Worker }
3062*8975f5c5SAndroid Build Coastguard Worker
3063*8975f5c5SAndroid Build Coastguard Worker if (levelImage->getHeight() != std::max(1, height >> level))
3064*8975f5c5SAndroid Build Coastguard Worker {
3065*8975f5c5SAndroid Build Coastguard Worker return false;
3066*8975f5c5SAndroid Build Coastguard Worker }
3067*8975f5c5SAndroid Build Coastguard Worker
3068*8975f5c5SAndroid Build Coastguard Worker if (levelImage->getDepth() != std::max(1, depth >> level))
3069*8975f5c5SAndroid Build Coastguard Worker {
3070*8975f5c5SAndroid Build Coastguard Worker return false;
3071*8975f5c5SAndroid Build Coastguard Worker }
3072*8975f5c5SAndroid Build Coastguard Worker
3073*8975f5c5SAndroid Build Coastguard Worker return true;
3074*8975f5c5SAndroid Build Coastguard Worker }
3075*8975f5c5SAndroid Build Coastguard Worker
isImageComplete(const gl::ImageIndex & index) const3076*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_3D::isImageComplete(const gl::ImageIndex &index) const
3077*8975f5c5SAndroid Build Coastguard Worker {
3078*8975f5c5SAndroid Build Coastguard Worker return isLevelComplete(index.getLevelIndex());
3079*8975f5c5SAndroid Build Coastguard Worker }
3080*8975f5c5SAndroid Build Coastguard Worker
updateStorageLevel(const gl::Context * context,int level)3081*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::updateStorageLevel(const gl::Context *context, int level)
3082*8975f5c5SAndroid Build Coastguard Worker {
3083*8975f5c5SAndroid Build Coastguard Worker ASSERT(level >= 0 && level < static_cast<int>(mImageArray.size()) &&
3084*8975f5c5SAndroid Build Coastguard Worker mImageArray[level] != nullptr);
3085*8975f5c5SAndroid Build Coastguard Worker ASSERT(isLevelComplete(level));
3086*8975f5c5SAndroid Build Coastguard Worker
3087*8975f5c5SAndroid Build Coastguard Worker if (mImageArray[level]->isDirty())
3088*8975f5c5SAndroid Build Coastguard Worker {
3089*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex index = gl::ImageIndex::Make3D(level);
3090*8975f5c5SAndroid Build Coastguard Worker gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
3091*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, region));
3092*8975f5c5SAndroid Build Coastguard Worker }
3093*8975f5c5SAndroid Build Coastguard Worker
3094*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3095*8975f5c5SAndroid Build Coastguard Worker }
3096*8975f5c5SAndroid Build Coastguard Worker
redefineImage(const gl::Context * context,GLint level,GLenum internalformat,const gl::Extents & size,bool forceRelease)3097*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_3D::redefineImage(const gl::Context *context,
3098*8975f5c5SAndroid Build Coastguard Worker GLint level,
3099*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
3100*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
3101*8975f5c5SAndroid Build Coastguard Worker bool forceRelease)
3102*8975f5c5SAndroid Build Coastguard Worker {
3103*8975f5c5SAndroid Build Coastguard Worker // If there currently is a corresponding storage texture image, it has these parameters
3104*8975f5c5SAndroid Build Coastguard Worker const int storageWidth = std::max(1, getLevelZeroWidth() >> level);
3105*8975f5c5SAndroid Build Coastguard Worker const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
3106*8975f5c5SAndroid Build Coastguard Worker const int storageDepth = std::max(1, getLevelZeroDepth() >> level);
3107*8975f5c5SAndroid Build Coastguard Worker const GLenum storageFormat = getBaseLevelInternalFormat();
3108*8975f5c5SAndroid Build Coastguard Worker
3109*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
3110*8975f5c5SAndroid Build Coastguard Worker {
3111*8975f5c5SAndroid Build Coastguard Worker const int storageLevels = mTexStorage->getLevelCount();
3112*8975f5c5SAndroid Build Coastguard Worker
3113*8975f5c5SAndroid Build Coastguard Worker if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
3114*8975f5c5SAndroid Build Coastguard Worker size.height != storageHeight || size.depth != storageDepth ||
3115*8975f5c5SAndroid Build Coastguard Worker internalformat != storageFormat) // Discard mismatched storage
3116*8975f5c5SAndroid Build Coastguard Worker {
3117*8975f5c5SAndroid Build Coastguard Worker markAllImagesDirty();
3118*8975f5c5SAndroid Build Coastguard Worker
3119*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask copyImageMask;
3120*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set();
3121*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set(level, false);
3122*8975f5c5SAndroid Build Coastguard Worker
3123*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, copyImageMask));
3124*8975f5c5SAndroid Build Coastguard Worker }
3125*8975f5c5SAndroid Build Coastguard Worker }
3126*8975f5c5SAndroid Build Coastguard Worker
3127*8975f5c5SAndroid Build Coastguard Worker mImageArray[level]->redefine(gl::TextureType::_3D, internalformat, size, forceRelease);
3128*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = mDirtyImages || mImageArray[level]->isDirty();
3129*8975f5c5SAndroid Build Coastguard Worker
3130*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3131*8975f5c5SAndroid Build Coastguard Worker }
3132*8975f5c5SAndroid Build Coastguard Worker
imageIterator() const3133*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator TextureD3D_3D::imageIterator() const
3134*8975f5c5SAndroid Build Coastguard Worker {
3135*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndexIterator::Make3D(0, mTexStorage->getLevelCount(),
3136*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex::kEntireLevel,
3137*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex::kEntireLevel);
3138*8975f5c5SAndroid Build Coastguard Worker }
3139*8975f5c5SAndroid Build Coastguard Worker
getImageIndex(GLint mip,GLint) const3140*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex TextureD3D_3D::getImageIndex(GLint mip, GLint /*layer*/) const
3141*8975f5c5SAndroid Build Coastguard Worker {
3142*8975f5c5SAndroid Build Coastguard Worker // The "layer" here does not apply to 3D images. We use one Image per mip.
3143*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndex::Make3D(mip);
3144*8975f5c5SAndroid Build Coastguard Worker }
3145*8975f5c5SAndroid Build Coastguard Worker
isValidIndex(const gl::ImageIndex & index) const3146*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_3D::isValidIndex(const gl::ImageIndex &index) const
3147*8975f5c5SAndroid Build Coastguard Worker {
3148*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage && index.getType() == gl::TextureType::_3D && index.getLevelIndex() >= 0 &&
3149*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex() < mTexStorage->getLevelCount());
3150*8975f5c5SAndroid Build Coastguard Worker }
3151*8975f5c5SAndroid Build Coastguard Worker
markAllImagesDirty()3152*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_3D::markAllImagesDirty()
3153*8975f5c5SAndroid Build Coastguard Worker {
3154*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
3155*8975f5c5SAndroid Build Coastguard Worker {
3156*8975f5c5SAndroid Build Coastguard Worker mImageArray[i]->markDirty();
3157*8975f5c5SAndroid Build Coastguard Worker }
3158*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
3159*8975f5c5SAndroid Build Coastguard Worker }
3160*8975f5c5SAndroid Build Coastguard Worker
getLevelZeroDepth() const3161*8975f5c5SAndroid Build Coastguard Worker GLint TextureD3D_3D::getLevelZeroDepth() const
3162*8975f5c5SAndroid Build Coastguard Worker {
3163*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::CountLeadingZeros(static_cast<uint32_t>(getBaseLevelDepth())) > getBaseLevel());
3164*8975f5c5SAndroid Build Coastguard Worker return getBaseLevelDepth() << getBaseLevel();
3165*8975f5c5SAndroid Build Coastguard Worker }
3166*8975f5c5SAndroid Build Coastguard Worker
TextureD3D_2DArray(const gl::TextureState & state,RendererD3D * renderer)3167*8975f5c5SAndroid Build Coastguard Worker TextureD3D_2DArray::TextureD3D_2DArray(const gl::TextureState &state, RendererD3D *renderer)
3168*8975f5c5SAndroid Build Coastguard Worker : TextureD3D(state, renderer)
3169*8975f5c5SAndroid Build Coastguard Worker {
3170*8975f5c5SAndroid Build Coastguard Worker for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
3171*8975f5c5SAndroid Build Coastguard Worker {
3172*8975f5c5SAndroid Build Coastguard Worker mLayerCounts[level] = 0;
3173*8975f5c5SAndroid Build Coastguard Worker mImageArray[level] = nullptr;
3174*8975f5c5SAndroid Build Coastguard Worker }
3175*8975f5c5SAndroid Build Coastguard Worker }
3176*8975f5c5SAndroid Build Coastguard Worker
onDestroy(const gl::Context * context)3177*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_2DArray::onDestroy(const gl::Context *context)
3178*8975f5c5SAndroid Build Coastguard Worker {
3179*8975f5c5SAndroid Build Coastguard Worker // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage
3180*8975f5c5SAndroid Build Coastguard Worker // for some of their data. If TextureStorage is deleted before the Images, then their data will
3181*8975f5c5SAndroid Build Coastguard Worker // be wastefully copied back from the GPU before we delete the Images.
3182*8975f5c5SAndroid Build Coastguard Worker deleteImages();
3183*8975f5c5SAndroid Build Coastguard Worker return TextureD3D::onDestroy(context);
3184*8975f5c5SAndroid Build Coastguard Worker }
3185*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D_2DArray()3186*8975f5c5SAndroid Build Coastguard Worker TextureD3D_2DArray::~TextureD3D_2DArray() {}
3187*8975f5c5SAndroid Build Coastguard Worker
getImage(int level,int layer) const3188*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_2DArray::getImage(int level, int layer) const
3189*8975f5c5SAndroid Build Coastguard Worker {
3190*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
3191*8975f5c5SAndroid Build Coastguard Worker ASSERT((layer == 0 && mLayerCounts[level] == 0) || layer < mLayerCounts[level]);
3192*8975f5c5SAndroid Build Coastguard Worker return (mImageArray[level] ? mImageArray[level][layer] : nullptr);
3193*8975f5c5SAndroid Build Coastguard Worker }
3194*8975f5c5SAndroid Build Coastguard Worker
getImage(const gl::ImageIndex & index) const3195*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const
3196*8975f5c5SAndroid Build Coastguard Worker {
3197*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
3198*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.hasLayer());
3199*8975f5c5SAndroid Build Coastguard Worker ASSERT((index.getLayerIndex() == 0 && mLayerCounts[index.getLevelIndex()] == 0) ||
3200*8975f5c5SAndroid Build Coastguard Worker index.getLayerIndex() < mLayerCounts[index.getLevelIndex()]);
3201*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getType() == gl::TextureType::_2DArray);
3202*8975f5c5SAndroid Build Coastguard Worker return (mImageArray[index.getLevelIndex()]
3203*8975f5c5SAndroid Build Coastguard Worker ? mImageArray[index.getLevelIndex()][index.getLayerIndex()]
3204*8975f5c5SAndroid Build Coastguard Worker : nullptr);
3205*8975f5c5SAndroid Build Coastguard Worker }
3206*8975f5c5SAndroid Build Coastguard Worker
getLayerCount(int level) const3207*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_2DArray::getLayerCount(int level) const
3208*8975f5c5SAndroid Build Coastguard Worker {
3209*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
3210*8975f5c5SAndroid Build Coastguard Worker return mLayerCounts[level];
3211*8975f5c5SAndroid Build Coastguard Worker }
3212*8975f5c5SAndroid Build Coastguard Worker
getWidth(GLint level) const3213*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_2DArray::getWidth(GLint level) const
3214*8975f5c5SAndroid Build Coastguard Worker {
3215*8975f5c5SAndroid Build Coastguard Worker return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0)
3216*8975f5c5SAndroid Build Coastguard Worker ? mImageArray[level][0]->getWidth()
3217*8975f5c5SAndroid Build Coastguard Worker : 0;
3218*8975f5c5SAndroid Build Coastguard Worker }
3219*8975f5c5SAndroid Build Coastguard Worker
getHeight(GLint level) const3220*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_2DArray::getHeight(GLint level) const
3221*8975f5c5SAndroid Build Coastguard Worker {
3222*8975f5c5SAndroid Build Coastguard Worker return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0)
3223*8975f5c5SAndroid Build Coastguard Worker ? mImageArray[level][0]->getHeight()
3224*8975f5c5SAndroid Build Coastguard Worker : 0;
3225*8975f5c5SAndroid Build Coastguard Worker }
3226*8975f5c5SAndroid Build Coastguard Worker
getInternalFormat(GLint level) const3227*8975f5c5SAndroid Build Coastguard Worker GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const
3228*8975f5c5SAndroid Build Coastguard Worker {
3229*8975f5c5SAndroid Build Coastguard Worker return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0)
3230*8975f5c5SAndroid Build Coastguard Worker ? mImageArray[level][0]->getInternalFormat()
3231*8975f5c5SAndroid Build Coastguard Worker : GL_NONE;
3232*8975f5c5SAndroid Build Coastguard Worker }
3233*8975f5c5SAndroid Build Coastguard Worker
isDepth(GLint level) const3234*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DArray::isDepth(GLint level) const
3235*8975f5c5SAndroid Build Coastguard Worker {
3236*8975f5c5SAndroid Build Coastguard Worker return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
3237*8975f5c5SAndroid Build Coastguard Worker }
3238*8975f5c5SAndroid Build Coastguard Worker
isSRGB(GLint level) const3239*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DArray::isSRGB(GLint level) const
3240*8975f5c5SAndroid Build Coastguard Worker {
3241*8975f5c5SAndroid Build Coastguard Worker return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB;
3242*8975f5c5SAndroid Build Coastguard Worker }
3243*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)3244*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::setEGLImageTarget(const gl::Context *context,
3245*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
3246*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
3247*8975f5c5SAndroid Build Coastguard Worker {
3248*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
3249*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3250*8975f5c5SAndroid Build Coastguard Worker }
3251*8975f5c5SAndroid Build Coastguard Worker
setImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)3252*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::setImage(const gl::Context *context,
3253*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3254*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
3255*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
3256*8975f5c5SAndroid Build Coastguard Worker GLenum format,
3257*8975f5c5SAndroid Build Coastguard Worker GLenum type,
3258*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
3259*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
3260*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
3261*8975f5c5SAndroid Build Coastguard Worker {
3262*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
3263*8975f5c5SAndroid Build Coastguard Worker
3264*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
3265*8975f5c5SAndroid Build Coastguard Worker
3266*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
3267*8975f5c5SAndroid Build Coastguard Worker redefineImage(context, index.getLevelIndex(), formatInfo.sizedInternalFormat, size, false));
3268*8975f5c5SAndroid Build Coastguard Worker
3269*8975f5c5SAndroid Build Coastguard Worker ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
3270*8975f5c5SAndroid Build Coastguard Worker
3271*8975f5c5SAndroid Build Coastguard Worker GLuint inputDepthPitch = 0;
3272*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeDepthPitch(
3273*8975f5c5SAndroid Build Coastguard Worker type, size.width, size.height, unpack.alignment,
3274*8975f5c5SAndroid Build Coastguard Worker unpack.rowLength, unpack.imageHeight, &inputDepthPitch));
3275*8975f5c5SAndroid Build Coastguard Worker
3276*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < size.depth; i++)
3277*8975f5c5SAndroid Build Coastguard Worker {
3278*8975f5c5SAndroid Build Coastguard Worker const ptrdiff_t layerOffset = (inputDepthPitch * i);
3279*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), i);
3280*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
3281*8975f5c5SAndroid Build Coastguard Worker setImageImpl(context, layerIndex, type, unpack, unpackBuffer, pixels, layerOffset));
3282*8975f5c5SAndroid Build Coastguard Worker }
3283*8975f5c5SAndroid Build Coastguard Worker
3284*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3285*8975f5c5SAndroid Build Coastguard Worker }
3286*8975f5c5SAndroid Build Coastguard Worker
setSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)3287*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::setSubImage(const gl::Context *context,
3288*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3289*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
3290*8975f5c5SAndroid Build Coastguard Worker GLenum format,
3291*8975f5c5SAndroid Build Coastguard Worker GLenum type,
3292*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
3293*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
3294*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
3295*8975f5c5SAndroid Build Coastguard Worker {
3296*8975f5c5SAndroid Build Coastguard Worker ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
3297*8975f5c5SAndroid Build Coastguard Worker
3298*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
3299*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &formatInfo =
3300*8975f5c5SAndroid Build Coastguard Worker gl::GetInternalFormatInfo(getInternalFormat(index.getLevelIndex()), type);
3301*8975f5c5SAndroid Build Coastguard Worker GLuint inputDepthPitch = 0;
3302*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeDepthPitch(
3303*8975f5c5SAndroid Build Coastguard Worker type, area.width, area.height, unpack.alignment,
3304*8975f5c5SAndroid Build Coastguard Worker unpack.rowLength, unpack.imageHeight, &inputDepthPitch));
3305*8975f5c5SAndroid Build Coastguard Worker
3306*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < area.depth; i++)
3307*8975f5c5SAndroid Build Coastguard Worker {
3308*8975f5c5SAndroid Build Coastguard Worker int layer = area.z + i;
3309*8975f5c5SAndroid Build Coastguard Worker const ptrdiff_t layerOffset = (inputDepthPitch * i);
3310*8975f5c5SAndroid Build Coastguard Worker
3311*8975f5c5SAndroid Build Coastguard Worker gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1);
3312*8975f5c5SAndroid Build Coastguard Worker
3313*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), layer);
3314*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(TextureD3D::subImage(context, layerIndex, layerArea, format, type, unpack,
3315*8975f5c5SAndroid Build Coastguard Worker unpackBuffer, pixels, layerOffset));
3316*8975f5c5SAndroid Build Coastguard Worker }
3317*8975f5c5SAndroid Build Coastguard Worker
3318*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3319*8975f5c5SAndroid Build Coastguard Worker }
3320*8975f5c5SAndroid Build Coastguard Worker
setCompressedImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)3321*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::setCompressedImage(const gl::Context *context,
3322*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3323*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
3324*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
3325*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
3326*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
3327*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
3328*8975f5c5SAndroid Build Coastguard Worker {
3329*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
3330*8975f5c5SAndroid Build Coastguard Worker
3331*8975f5c5SAndroid Build Coastguard Worker ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
3332*8975f5c5SAndroid Build Coastguard Worker
3333*8975f5c5SAndroid Build Coastguard Worker // compressed formats don't have separate sized internal formats-- we can just use the
3334*8975f5c5SAndroid Build Coastguard Worker // compressed format directly
3335*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false));
3336*8975f5c5SAndroid Build Coastguard Worker
3337*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
3338*8975f5c5SAndroid Build Coastguard Worker GLuint inputDepthPitch = 0;
3339*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(
3340*8975f5c5SAndroid Build Coastguard Worker contextD3D, formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0, 0,
3341*8975f5c5SAndroid Build Coastguard Worker &inputDepthPitch));
3342*8975f5c5SAndroid Build Coastguard Worker
3343*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < size.depth; i++)
3344*8975f5c5SAndroid Build Coastguard Worker {
3345*8975f5c5SAndroid Build Coastguard Worker const ptrdiff_t layerOffset = (inputDepthPitch * i);
3346*8975f5c5SAndroid Build Coastguard Worker
3347*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), i);
3348*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompressedImageImpl(context, layerIndex, unpack, pixels, layerOffset));
3349*8975f5c5SAndroid Build Coastguard Worker }
3350*8975f5c5SAndroid Build Coastguard Worker
3351*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3352*8975f5c5SAndroid Build Coastguard Worker }
3353*8975f5c5SAndroid Build Coastguard Worker
setCompressedSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)3354*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::setCompressedSubImage(const gl::Context *context,
3355*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3356*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
3357*8975f5c5SAndroid Build Coastguard Worker GLenum format,
3358*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
3359*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
3360*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
3361*8975f5c5SAndroid Build Coastguard Worker {
3362*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
3363*8975f5c5SAndroid Build Coastguard Worker
3364*8975f5c5SAndroid Build Coastguard Worker ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
3365*8975f5c5SAndroid Build Coastguard Worker
3366*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format);
3367*8975f5c5SAndroid Build Coastguard Worker GLuint inputDepthPitch = 0;
3368*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(
3369*8975f5c5SAndroid Build Coastguard Worker contextD3D, formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0,
3370*8975f5c5SAndroid Build Coastguard Worker &inputDepthPitch));
3371*8975f5c5SAndroid Build Coastguard Worker
3372*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < area.depth; i++)
3373*8975f5c5SAndroid Build Coastguard Worker {
3374*8975f5c5SAndroid Build Coastguard Worker int layer = area.z + i;
3375*8975f5c5SAndroid Build Coastguard Worker const ptrdiff_t layerOffset = (inputDepthPitch * i);
3376*8975f5c5SAndroid Build Coastguard Worker
3377*8975f5c5SAndroid Build Coastguard Worker gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1);
3378*8975f5c5SAndroid Build Coastguard Worker
3379*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), layer);
3380*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(TextureD3D::subImageCompressed(context, layerIndex, layerArea, format, unpack,
3381*8975f5c5SAndroid Build Coastguard Worker pixels, layerOffset));
3382*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, layerIndex, layerArea));
3383*8975f5c5SAndroid Build Coastguard Worker }
3384*8975f5c5SAndroid Build Coastguard Worker
3385*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3386*8975f5c5SAndroid Build Coastguard Worker }
3387*8975f5c5SAndroid Build Coastguard Worker
copyImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Rectangle & sourceArea,GLenum internalFormat,gl::Framebuffer * source)3388*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::copyImage(const gl::Context *context,
3389*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3390*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
3391*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
3392*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
3393*8975f5c5SAndroid Build Coastguard Worker {
3394*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
3395*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3396*8975f5c5SAndroid Build Coastguard Worker }
3397*8975f5c5SAndroid Build Coastguard Worker
copySubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,const gl::Rectangle & sourceArea,gl::Framebuffer * source)3398*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::copySubImage(const gl::Context *context,
3399*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3400*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
3401*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
3402*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
3403*8975f5c5SAndroid Build Coastguard Worker {
3404*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
3405*8975f5c5SAndroid Build Coastguard Worker
3406*8975f5c5SAndroid Build Coastguard Worker gl::Extents fbSize = source->getReadColorAttachment()->getSize();
3407*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedSourceArea;
3408*8975f5c5SAndroid Build Coastguard Worker if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
3409*8975f5c5SAndroid Build Coastguard Worker &clippedSourceArea))
3410*8975f5c5SAndroid Build Coastguard Worker {
3411*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3412*8975f5c5SAndroid Build Coastguard Worker }
3413*8975f5c5SAndroid Build Coastguard Worker const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x,
3414*8975f5c5SAndroid Build Coastguard Worker destOffset.y + clippedSourceArea.y - sourceArea.y,
3415*8975f5c5SAndroid Build Coastguard Worker destOffset.z);
3416*8975f5c5SAndroid Build Coastguard Worker
3417*8975f5c5SAndroid Build Coastguard Worker if (!canCreateRenderTargetForImage(index))
3418*8975f5c5SAndroid Build Coastguard Worker {
3419*8975f5c5SAndroid Build Coastguard Worker gl::Offset destLayerOffset(clippedDestOffset.x, clippedDestOffset.y, 0);
3420*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mImageArray[index.getLevelIndex()][clippedDestOffset.z]->copyFromFramebuffer(
3421*8975f5c5SAndroid Build Coastguard Worker context, destLayerOffset, clippedSourceArea, source));
3422*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
3423*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
3424*8975f5c5SAndroid Build Coastguard Worker }
3425*8975f5c5SAndroid Build Coastguard Worker else
3426*8975f5c5SAndroid Build Coastguard Worker {
3427*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
3428*8975f5c5SAndroid Build Coastguard Worker
3429*8975f5c5SAndroid Build Coastguard Worker if (isValidLevel(index.getLevelIndex()))
3430*8975f5c5SAndroid Build Coastguard Worker {
3431*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
3432*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
3433*8975f5c5SAndroid Build Coastguard Worker mRenderer->copyImage2DArray(context, source, clippedSourceArea,
3434*8975f5c5SAndroid Build Coastguard Worker gl::GetUnsizedFormat(getInternalFormat(getBaseLevel())),
3435*8975f5c5SAndroid Build Coastguard Worker clippedDestOffset, mTexStorage, index.getLevelIndex()));
3436*8975f5c5SAndroid Build Coastguard Worker }
3437*8975f5c5SAndroid Build Coastguard Worker }
3438*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3439*8975f5c5SAndroid Build Coastguard Worker }
3440*8975f5c5SAndroid Build Coastguard Worker
copyTexture(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,GLenum type,GLint sourceLevel,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)3441*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::copyTexture(const gl::Context *context,
3442*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3443*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
3444*8975f5c5SAndroid Build Coastguard Worker GLenum type,
3445*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
3446*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
3447*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
3448*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
3449*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
3450*8975f5c5SAndroid Build Coastguard Worker {
3451*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
3452*8975f5c5SAndroid Build Coastguard Worker
3453*8975f5c5SAndroid Build Coastguard Worker gl::TextureType sourceType = source->getType();
3454*8975f5c5SAndroid Build Coastguard Worker
3455*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
3456*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(
3457*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
3458*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
3459*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(source->getDepth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)));
3460*8975f5c5SAndroid Build Coastguard Worker
3461*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
3462*8975f5c5SAndroid Build Coastguard Worker size, false));
3463*8975f5c5SAndroid Build Coastguard Worker
3464*8975f5c5SAndroid Build Coastguard Worker gl::Box sourceBox(0, 0, 0, size.width, size.height, size.depth);
3465*8975f5c5SAndroid Build Coastguard Worker gl::Offset destOffset(0, 0, 0);
3466*8975f5c5SAndroid Build Coastguard Worker
3467*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex destIndex =
3468*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex::Make2DArrayRange(index.getLevelIndex(), 0, size.depth);
3469*8975f5c5SAndroid Build Coastguard Worker
3470*8975f5c5SAndroid Build Coastguard Worker if (!isSRGB(index.getLevelIndex()) &&
3471*8975f5c5SAndroid Build Coastguard Worker canCreateRenderTargetForImage(
3472*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex::Make2DArrayRange(index.getLevelIndex(), 0, size.depth)))
3473*8975f5c5SAndroid Build Coastguard Worker {
3474*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
3475*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidLevel(index.getLevelIndex()));
3476*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
3477*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2DArray,
3478*8975f5c5SAndroid Build Coastguard Worker sourceBox, internalFormatInfo.format,
3479*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type, destOffset, mTexStorage,
3480*8975f5c5SAndroid Build Coastguard Worker index.getTarget(), index.getLevelIndex(), unpackFlipY,
3481*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
3482*8975f5c5SAndroid Build Coastguard Worker }
3483*8975f5c5SAndroid Build Coastguard Worker else
3484*8975f5c5SAndroid Build Coastguard Worker {
3485*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < size.depth; i++)
3486*8975f5c5SAndroid Build Coastguard Worker {
3487*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex currentSourceDepthIndex = gl::ImageIndex::Make2DArray(sourceLevel, i);
3488*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex currentDestDepthIndex =
3489*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex::Make2DArray(index.getLevelIndex(), i);
3490*8975f5c5SAndroid Build Coastguard Worker ImageD3D *sourceImage = nullptr;
3491*8975f5c5SAndroid Build Coastguard Worker ImageD3D *destImage = nullptr;
3492*8975f5c5SAndroid Build Coastguard Worker TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
3493*8975f5c5SAndroid Build Coastguard Worker
3494*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImageAndSyncFromStorage(context, currentDestDepthIndex, &destImage));
3495*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, currentSourceDepthIndex,
3496*8975f5c5SAndroid Build Coastguard Worker &sourceImage));
3497*8975f5c5SAndroid Build Coastguard Worker gl::Box imageBox(sourceBox.x, sourceBox.y, 0, sourceBox.width, sourceBox.height, 1);
3498*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, imageBox, destOffset,
3499*8975f5c5SAndroid Build Coastguard Worker unpackFlipY, unpackPremultiplyAlpha,
3500*8975f5c5SAndroid Build Coastguard Worker unpackUnmultiplyAlpha));
3501*8975f5c5SAndroid Build Coastguard Worker }
3502*8975f5c5SAndroid Build Coastguard Worker
3503*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
3504*8975f5c5SAndroid Build Coastguard Worker
3505*8975f5c5SAndroid Build Coastguard Worker gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width,
3506*8975f5c5SAndroid Build Coastguard Worker sourceBox.height, sourceBox.depth);
3507*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, destIndex, destRegion));
3508*8975f5c5SAndroid Build Coastguard Worker }
3509*8975f5c5SAndroid Build Coastguard Worker
3510*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3511*8975f5c5SAndroid Build Coastguard Worker }
3512*8975f5c5SAndroid Build Coastguard Worker
copySubTexture(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,GLint sourceLevel,const gl::Box & sourceBox,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)3513*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::copySubTexture(const gl::Context *context,
3514*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3515*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
3516*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
3517*8975f5c5SAndroid Build Coastguard Worker const gl::Box &sourceBox,
3518*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
3519*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
3520*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
3521*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
3522*8975f5c5SAndroid Build Coastguard Worker {
3523*8975f5c5SAndroid Build Coastguard Worker ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
3524*8975f5c5SAndroid Build Coastguard Worker
3525*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex destIndex = gl::ImageIndex::Make2DArrayRange(
3526*8975f5c5SAndroid Build Coastguard Worker static_cast<GLint>(index.getLevelIndex()), destOffset.z, sourceBox.depth - destOffset.z);
3527*8975f5c5SAndroid Build Coastguard Worker
3528*8975f5c5SAndroid Build Coastguard Worker if (!isSRGB(destIndex.getLevelIndex()) && canCreateRenderTargetForImage(destIndex))
3529*8975f5c5SAndroid Build Coastguard Worker {
3530*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
3531*8975f5c5SAndroid Build Coastguard Worker ASSERT(isValidLevel(destIndex.getLevelIndex()));
3532*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, destIndex.getLevelIndex()));
3533*8975f5c5SAndroid Build Coastguard Worker
3534*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
3535*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(getInternalFormat(destIndex.getLevelIndex()));
3536*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2DArray,
3537*8975f5c5SAndroid Build Coastguard Worker sourceBox, internalFormatInfo.format,
3538*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type, destOffset, mTexStorage,
3539*8975f5c5SAndroid Build Coastguard Worker index.getTarget(), index.getLevelIndex(), unpackFlipY,
3540*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
3541*8975f5c5SAndroid Build Coastguard Worker }
3542*8975f5c5SAndroid Build Coastguard Worker else
3543*8975f5c5SAndroid Build Coastguard Worker {
3544*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < sourceBox.depth; i++)
3545*8975f5c5SAndroid Build Coastguard Worker {
3546*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex currentSourceIndex =
3547*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex::Make2DArray(sourceLevel, i + sourceBox.z);
3548*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex currentDestIndex =
3549*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex::Make2DArray(index.getLevelIndex(), i + destOffset.z);
3550*8975f5c5SAndroid Build Coastguard Worker
3551*8975f5c5SAndroid Build Coastguard Worker gl::Box currentLayerBox(sourceBox.x, sourceBox.y, 0, sourceBox.width, sourceBox.height,
3552*8975f5c5SAndroid Build Coastguard Worker 1);
3553*8975f5c5SAndroid Build Coastguard Worker
3554*8975f5c5SAndroid Build Coastguard Worker TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
3555*8975f5c5SAndroid Build Coastguard Worker ImageD3D *sourceImage = nullptr;
3556*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
3557*8975f5c5SAndroid Build Coastguard Worker sourceD3D->getImageAndSyncFromStorage(context, currentSourceIndex, &sourceImage));
3558*8975f5c5SAndroid Build Coastguard Worker
3559*8975f5c5SAndroid Build Coastguard Worker ImageD3D *destImage = nullptr;
3560*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getImageAndSyncFromStorage(context, currentDestIndex, &destImage));
3561*8975f5c5SAndroid Build Coastguard Worker
3562*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, currentLayerBox,
3563*8975f5c5SAndroid Build Coastguard Worker destOffset, unpackFlipY, unpackPremultiplyAlpha,
3564*8975f5c5SAndroid Build Coastguard Worker unpackUnmultiplyAlpha));
3565*8975f5c5SAndroid Build Coastguard Worker }
3566*8975f5c5SAndroid Build Coastguard Worker
3567*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
3568*8975f5c5SAndroid Build Coastguard Worker
3569*8975f5c5SAndroid Build Coastguard Worker gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width,
3570*8975f5c5SAndroid Build Coastguard Worker sourceBox.height, sourceBox.depth);
3571*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, destIndex, destRegion));
3572*8975f5c5SAndroid Build Coastguard Worker }
3573*8975f5c5SAndroid Build Coastguard Worker
3574*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3575*8975f5c5SAndroid Build Coastguard Worker }
3576*8975f5c5SAndroid Build Coastguard Worker
setStorage(const gl::Context * context,gl::TextureType type,size_t levels,GLenum internalFormat,const gl::Extents & size)3577*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::setStorage(const gl::Context *context,
3578*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
3579*8975f5c5SAndroid Build Coastguard Worker size_t levels,
3580*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
3581*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size)
3582*8975f5c5SAndroid Build Coastguard Worker {
3583*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == gl::TextureType::_2DArray);
3584*8975f5c5SAndroid Build Coastguard Worker
3585*8975f5c5SAndroid Build Coastguard Worker deleteImages();
3586*8975f5c5SAndroid Build Coastguard Worker
3587*8975f5c5SAndroid Build Coastguard Worker for (size_t level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
3588*8975f5c5SAndroid Build Coastguard Worker {
3589*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelLayerSize(std::max(1, size.width >> level),
3590*8975f5c5SAndroid Build Coastguard Worker std::max(1, size.height >> level), 1);
3591*8975f5c5SAndroid Build Coastguard Worker
3592*8975f5c5SAndroid Build Coastguard Worker mLayerCounts[level] = (level < levels ? size.depth : 0);
3593*8975f5c5SAndroid Build Coastguard Worker
3594*8975f5c5SAndroid Build Coastguard Worker if (mLayerCounts[level] > 0)
3595*8975f5c5SAndroid Build Coastguard Worker {
3596*8975f5c5SAndroid Build Coastguard Worker // Create new images for this level
3597*8975f5c5SAndroid Build Coastguard Worker mImageArray[level] = new ImageD3D *[mLayerCounts[level]];
3598*8975f5c5SAndroid Build Coastguard Worker
3599*8975f5c5SAndroid Build Coastguard Worker for (int layer = 0; layer < mLayerCounts[level]; layer++)
3600*8975f5c5SAndroid Build Coastguard Worker {
3601*8975f5c5SAndroid Build Coastguard Worker mImageArray[level][layer] = mRenderer->createImage();
3602*8975f5c5SAndroid Build Coastguard Worker mImageArray[level][layer]->redefine(gl::TextureType::_2DArray, internalFormat,
3603*8975f5c5SAndroid Build Coastguard Worker levelLayerSize, true);
3604*8975f5c5SAndroid Build Coastguard Worker }
3605*8975f5c5SAndroid Build Coastguard Worker }
3606*8975f5c5SAndroid Build Coastguard Worker }
3607*8975f5c5SAndroid Build Coastguard Worker
3608*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Verify storage creation had no errors
3609*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags;
3610*8975f5c5SAndroid Build Coastguard Worker bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage());
3611*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage = {mRenderer->createTextureStorage2DArray(
3612*8975f5c5SAndroid Build Coastguard Worker internalFormat, bindFlags, size.width, size.height, size.depth,
3613*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(levels), mState.getLabel()),
3614*8975f5c5SAndroid Build Coastguard Worker context};
3615*8975f5c5SAndroid Build Coastguard Worker
3616*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
3617*8975f5c5SAndroid Build Coastguard Worker storage.release();
3618*8975f5c5SAndroid Build Coastguard Worker
3619*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
3620*8975f5c5SAndroid Build Coastguard Worker
3621*8975f5c5SAndroid Build Coastguard Worker mImmutable = true;
3622*8975f5c5SAndroid Build Coastguard Worker
3623*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3624*8975f5c5SAndroid Build Coastguard Worker }
3625*8975f5c5SAndroid Build Coastguard Worker
bindTexImage(const gl::Context * context,egl::Surface * surface)3626*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::bindTexImage(const gl::Context *context, egl::Surface *surface)
3627*8975f5c5SAndroid Build Coastguard Worker {
3628*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
3629*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3630*8975f5c5SAndroid Build Coastguard Worker }
3631*8975f5c5SAndroid Build Coastguard Worker
releaseTexImage(const gl::Context * context)3632*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::releaseTexImage(const gl::Context *context)
3633*8975f5c5SAndroid Build Coastguard Worker {
3634*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
3635*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3636*8975f5c5SAndroid Build Coastguard Worker }
3637*8975f5c5SAndroid Build Coastguard Worker
initMipmapImages(const gl::Context * context)3638*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::initMipmapImages(const gl::Context *context)
3639*8975f5c5SAndroid Build Coastguard Worker {
3640*8975f5c5SAndroid Build Coastguard Worker const GLuint baseLevel = mState.getEffectiveBaseLevel();
3641*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = mState.getMipmapMaxLevel();
3642*8975f5c5SAndroid Build Coastguard Worker int baseWidth = getLevelZeroWidth();
3643*8975f5c5SAndroid Build Coastguard Worker int baseHeight = getLevelZeroHeight();
3644*8975f5c5SAndroid Build Coastguard Worker int baseDepth = getLayerCount(getBaseLevel());
3645*8975f5c5SAndroid Build Coastguard Worker GLenum baseFormat = getBaseLevelInternalFormat();
3646*8975f5c5SAndroid Build Coastguard Worker
3647*8975f5c5SAndroid Build Coastguard Worker // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap
3648*8975f5c5SAndroid Build Coastguard Worker // levels.
3649*8975f5c5SAndroid Build Coastguard Worker for (GLuint level = baseLevel + 1u; level <= maxLevel; level++)
3650*8975f5c5SAndroid Build Coastguard Worker {
3651*8975f5c5SAndroid Build Coastguard Worker ASSERT((baseWidth >> level) > 0 || (baseHeight >> level) > 0);
3652*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelLayerSize(std::max(baseWidth >> level, 1),
3653*8975f5c5SAndroid Build Coastguard Worker std::max(baseHeight >> level, 1), baseDepth);
3654*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(redefineImage(context, level, baseFormat, levelLayerSize, false));
3655*8975f5c5SAndroid Build Coastguard Worker }
3656*8975f5c5SAndroid Build Coastguard Worker
3657*8975f5c5SAndroid Build Coastguard Worker // We should be mip-complete now so generate the storage.
3658*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget()));
3659*8975f5c5SAndroid Build Coastguard Worker
3660*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3661*8975f5c5SAndroid Build Coastguard Worker }
3662*8975f5c5SAndroid Build Coastguard Worker
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)3663*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::getRenderTarget(const gl::Context *context,
3664*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3665*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
3666*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D **outRT)
3667*8975f5c5SAndroid Build Coastguard Worker {
3668*8975f5c5SAndroid Build Coastguard Worker // ensure the underlying texture is created
3669*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
3670*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
3671*8975f5c5SAndroid Build Coastguard Worker return mTexStorage->getRenderTarget(context, index, samples, outRT);
3672*8975f5c5SAndroid Build Coastguard Worker }
3673*8975f5c5SAndroid Build Coastguard Worker
initializeStorage(const gl::Context * context,BindFlags bindFlags)3674*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::initializeStorage(const gl::Context *context, BindFlags bindFlags)
3675*8975f5c5SAndroid Build Coastguard Worker {
3676*8975f5c5SAndroid Build Coastguard Worker // Only initialize the first time this texture is used as a render target or shader resource
3677*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
3678*8975f5c5SAndroid Build Coastguard Worker {
3679*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3680*8975f5c5SAndroid Build Coastguard Worker }
3681*8975f5c5SAndroid Build Coastguard Worker
3682*8975f5c5SAndroid Build Coastguard Worker // do not attempt to create storage for nonexistant data
3683*8975f5c5SAndroid Build Coastguard Worker if (!isLevelComplete(getBaseLevel()))
3684*8975f5c5SAndroid Build Coastguard Worker {
3685*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3686*8975f5c5SAndroid Build Coastguard Worker }
3687*8975f5c5SAndroid Build Coastguard Worker
3688*8975f5c5SAndroid Build Coastguard Worker bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage());
3689*8975f5c5SAndroid Build Coastguard Worker
3690*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage;
3691*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage));
3692*8975f5c5SAndroid Build Coastguard Worker
3693*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
3694*8975f5c5SAndroid Build Coastguard Worker storage.release();
3695*8975f5c5SAndroid Build Coastguard Worker
3696*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
3697*8975f5c5SAndroid Build Coastguard Worker
3698*8975f5c5SAndroid Build Coastguard Worker // flush image data to the storage
3699*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorage(context));
3700*8975f5c5SAndroid Build Coastguard Worker
3701*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3702*8975f5c5SAndroid Build Coastguard Worker }
3703*8975f5c5SAndroid Build Coastguard Worker
createCompleteStorage(const gl::Context * context,BindFlags bindFlags,TexStoragePointer * outStorage) const3704*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::createCompleteStorage(const gl::Context *context,
3705*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags,
3706*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer *outStorage) const
3707*8975f5c5SAndroid Build Coastguard Worker {
3708*8975f5c5SAndroid Build Coastguard Worker GLsizei width = getLevelZeroWidth();
3709*8975f5c5SAndroid Build Coastguard Worker GLsizei height = getLevelZeroHeight();
3710*8975f5c5SAndroid Build Coastguard Worker GLsizei depth = getLayerCount(getBaseLevel());
3711*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat = getBaseLevelInternalFormat();
3712*8975f5c5SAndroid Build Coastguard Worker
3713*8975f5c5SAndroid Build Coastguard Worker ASSERT(width > 0 && height > 0 && depth > 0);
3714*8975f5c5SAndroid Build Coastguard Worker
3715*8975f5c5SAndroid Build Coastguard Worker // use existing storage level count, when previously specified by TexStorage*D
3716*8975f5c5SAndroid Build Coastguard Worker GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
3717*8975f5c5SAndroid Build Coastguard Worker
3718*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Verify storage creation succeeds
3719*8975f5c5SAndroid Build Coastguard Worker *outStorage = {mRenderer->createTextureStorage2DArray(internalFormat, bindFlags, width, height,
3720*8975f5c5SAndroid Build Coastguard Worker depth, levels, mState.getLabel()),
3721*8975f5c5SAndroid Build Coastguard Worker context};
3722*8975f5c5SAndroid Build Coastguard Worker
3723*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3724*8975f5c5SAndroid Build Coastguard Worker }
3725*8975f5c5SAndroid Build Coastguard Worker
setCompleteTexStorage(const gl::Context * context,TextureStorage * newCompleteTexStorage)3726*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::setCompleteTexStorage(const gl::Context *context,
3727*8975f5c5SAndroid Build Coastguard Worker TextureStorage *newCompleteTexStorage)
3728*8975f5c5SAndroid Build Coastguard Worker {
3729*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask copyImageMask;
3730*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set();
3731*8975f5c5SAndroid Build Coastguard Worker
3732*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, copyImageMask));
3733*8975f5c5SAndroid Build Coastguard Worker mTexStorage = newCompleteTexStorage;
3734*8975f5c5SAndroid Build Coastguard Worker mTexStorageObserverBinding.bind(mTexStorage);
3735*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
3736*8975f5c5SAndroid Build Coastguard Worker
3737*8975f5c5SAndroid Build Coastguard Worker // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
3738*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mTexStorage->isManaged());
3739*8975f5c5SAndroid Build Coastguard Worker
3740*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3741*8975f5c5SAndroid Build Coastguard Worker }
3742*8975f5c5SAndroid Build Coastguard Worker
updateStorage(const gl::Context * context)3743*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::updateStorage(const gl::Context *context)
3744*8975f5c5SAndroid Build Coastguard Worker {
3745*8975f5c5SAndroid Build Coastguard Worker if (!mDirtyImages)
3746*8975f5c5SAndroid Build Coastguard Worker {
3747*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3748*8975f5c5SAndroid Build Coastguard Worker }
3749*8975f5c5SAndroid Build Coastguard Worker
3750*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage != nullptr);
3751*8975f5c5SAndroid Build Coastguard Worker GLint storageLevels = mTexStorage->getLevelCount();
3752*8975f5c5SAndroid Build Coastguard Worker for (int level = 0; level < storageLevels; level++)
3753*8975f5c5SAndroid Build Coastguard Worker {
3754*8975f5c5SAndroid Build Coastguard Worker if (isLevelComplete(level))
3755*8975f5c5SAndroid Build Coastguard Worker {
3756*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(updateStorageLevel(context, level));
3757*8975f5c5SAndroid Build Coastguard Worker }
3758*8975f5c5SAndroid Build Coastguard Worker }
3759*8975f5c5SAndroid Build Coastguard Worker
3760*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = false;
3761*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3762*8975f5c5SAndroid Build Coastguard Worker }
3763*8975f5c5SAndroid Build Coastguard Worker
isValidLevel(int level) const3764*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DArray::isValidLevel(int level) const
3765*8975f5c5SAndroid Build Coastguard Worker {
3766*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
3767*8975f5c5SAndroid Build Coastguard Worker }
3768*8975f5c5SAndroid Build Coastguard Worker
isLevelComplete(int level) const3769*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DArray::isLevelComplete(int level) const
3770*8975f5c5SAndroid Build Coastguard Worker {
3771*8975f5c5SAndroid Build Coastguard Worker ASSERT(level >= 0 && level < (int)ArraySize(mImageArray));
3772*8975f5c5SAndroid Build Coastguard Worker
3773*8975f5c5SAndroid Build Coastguard Worker if (isImmutable())
3774*8975f5c5SAndroid Build Coastguard Worker {
3775*8975f5c5SAndroid Build Coastguard Worker return true;
3776*8975f5c5SAndroid Build Coastguard Worker }
3777*8975f5c5SAndroid Build Coastguard Worker
3778*8975f5c5SAndroid Build Coastguard Worker GLsizei width = getLevelZeroWidth();
3779*8975f5c5SAndroid Build Coastguard Worker GLsizei height = getLevelZeroHeight();
3780*8975f5c5SAndroid Build Coastguard Worker
3781*8975f5c5SAndroid Build Coastguard Worker if (width <= 0 || height <= 0)
3782*8975f5c5SAndroid Build Coastguard Worker {
3783*8975f5c5SAndroid Build Coastguard Worker return false;
3784*8975f5c5SAndroid Build Coastguard Worker }
3785*8975f5c5SAndroid Build Coastguard Worker
3786*8975f5c5SAndroid Build Coastguard Worker // Layers check needs to happen after the above checks, otherwise out-of-range base level may be
3787*8975f5c5SAndroid Build Coastguard Worker // queried.
3788*8975f5c5SAndroid Build Coastguard Worker GLsizei layers = getLayerCount(getBaseLevel());
3789*8975f5c5SAndroid Build Coastguard Worker
3790*8975f5c5SAndroid Build Coastguard Worker if (layers <= 0)
3791*8975f5c5SAndroid Build Coastguard Worker {
3792*8975f5c5SAndroid Build Coastguard Worker return false;
3793*8975f5c5SAndroid Build Coastguard Worker }
3794*8975f5c5SAndroid Build Coastguard Worker
3795*8975f5c5SAndroid Build Coastguard Worker if (level == static_cast<int>(getBaseLevel()))
3796*8975f5c5SAndroid Build Coastguard Worker {
3797*8975f5c5SAndroid Build Coastguard Worker return true;
3798*8975f5c5SAndroid Build Coastguard Worker }
3799*8975f5c5SAndroid Build Coastguard Worker
3800*8975f5c5SAndroid Build Coastguard Worker if (getInternalFormat(level) != getInternalFormat(getBaseLevel()))
3801*8975f5c5SAndroid Build Coastguard Worker {
3802*8975f5c5SAndroid Build Coastguard Worker return false;
3803*8975f5c5SAndroid Build Coastguard Worker }
3804*8975f5c5SAndroid Build Coastguard Worker
3805*8975f5c5SAndroid Build Coastguard Worker if (getWidth(level) != std::max(1, width >> level))
3806*8975f5c5SAndroid Build Coastguard Worker {
3807*8975f5c5SAndroid Build Coastguard Worker return false;
3808*8975f5c5SAndroid Build Coastguard Worker }
3809*8975f5c5SAndroid Build Coastguard Worker
3810*8975f5c5SAndroid Build Coastguard Worker if (getHeight(level) != std::max(1, height >> level))
3811*8975f5c5SAndroid Build Coastguard Worker {
3812*8975f5c5SAndroid Build Coastguard Worker return false;
3813*8975f5c5SAndroid Build Coastguard Worker }
3814*8975f5c5SAndroid Build Coastguard Worker
3815*8975f5c5SAndroid Build Coastguard Worker if (getLayerCount(level) != layers)
3816*8975f5c5SAndroid Build Coastguard Worker {
3817*8975f5c5SAndroid Build Coastguard Worker return false;
3818*8975f5c5SAndroid Build Coastguard Worker }
3819*8975f5c5SAndroid Build Coastguard Worker
3820*8975f5c5SAndroid Build Coastguard Worker return true;
3821*8975f5c5SAndroid Build Coastguard Worker }
3822*8975f5c5SAndroid Build Coastguard Worker
isImageComplete(const gl::ImageIndex & index) const3823*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DArray::isImageComplete(const gl::ImageIndex &index) const
3824*8975f5c5SAndroid Build Coastguard Worker {
3825*8975f5c5SAndroid Build Coastguard Worker return isLevelComplete(index.getLevelIndex());
3826*8975f5c5SAndroid Build Coastguard Worker }
3827*8975f5c5SAndroid Build Coastguard Worker
updateStorageLevel(const gl::Context * context,int level)3828*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::updateStorageLevel(const gl::Context *context, int level)
3829*8975f5c5SAndroid Build Coastguard Worker {
3830*8975f5c5SAndroid Build Coastguard Worker ASSERT(level >= 0 && level < static_cast<int>(ArraySize(mLayerCounts)));
3831*8975f5c5SAndroid Build Coastguard Worker ASSERT(isLevelComplete(level));
3832*8975f5c5SAndroid Build Coastguard Worker
3833*8975f5c5SAndroid Build Coastguard Worker for (int layer = 0; layer < mLayerCounts[level]; layer++)
3834*8975f5c5SAndroid Build Coastguard Worker {
3835*8975f5c5SAndroid Build Coastguard Worker ASSERT(mImageArray[level] != nullptr && mImageArray[level][layer] != nullptr);
3836*8975f5c5SAndroid Build Coastguard Worker if (mImageArray[level][layer]->isDirty())
3837*8975f5c5SAndroid Build Coastguard Worker {
3838*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
3839*8975f5c5SAndroid Build Coastguard Worker gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
3840*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(commitRegion(context, index, region));
3841*8975f5c5SAndroid Build Coastguard Worker }
3842*8975f5c5SAndroid Build Coastguard Worker }
3843*8975f5c5SAndroid Build Coastguard Worker
3844*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3845*8975f5c5SAndroid Build Coastguard Worker }
3846*8975f5c5SAndroid Build Coastguard Worker
deleteImages()3847*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_2DArray::deleteImages()
3848*8975f5c5SAndroid Build Coastguard Worker {
3849*8975f5c5SAndroid Build Coastguard Worker for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
3850*8975f5c5SAndroid Build Coastguard Worker {
3851*8975f5c5SAndroid Build Coastguard Worker for (int layer = 0; layer < mLayerCounts[level]; ++layer)
3852*8975f5c5SAndroid Build Coastguard Worker {
3853*8975f5c5SAndroid Build Coastguard Worker delete mImageArray[level][layer];
3854*8975f5c5SAndroid Build Coastguard Worker }
3855*8975f5c5SAndroid Build Coastguard Worker delete[] mImageArray[level];
3856*8975f5c5SAndroid Build Coastguard Worker mImageArray[level] = nullptr;
3857*8975f5c5SAndroid Build Coastguard Worker mLayerCounts[level] = 0;
3858*8975f5c5SAndroid Build Coastguard Worker }
3859*8975f5c5SAndroid Build Coastguard Worker }
3860*8975f5c5SAndroid Build Coastguard Worker
redefineImage(const gl::Context * context,GLint level,GLenum internalformat,const gl::Extents & size,bool forceRelease)3861*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DArray::redefineImage(const gl::Context *context,
3862*8975f5c5SAndroid Build Coastguard Worker GLint level,
3863*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
3864*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
3865*8975f5c5SAndroid Build Coastguard Worker bool forceRelease)
3866*8975f5c5SAndroid Build Coastguard Worker {
3867*8975f5c5SAndroid Build Coastguard Worker // If there currently is a corresponding storage texture image, it has these parameters
3868*8975f5c5SAndroid Build Coastguard Worker const int storageWidth = std::max(1, getLevelZeroWidth() >> level);
3869*8975f5c5SAndroid Build Coastguard Worker const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
3870*8975f5c5SAndroid Build Coastguard Worker const GLuint baseLevel = getBaseLevel();
3871*8975f5c5SAndroid Build Coastguard Worker const GLenum storageFormat = getBaseLevelInternalFormat();
3872*8975f5c5SAndroid Build Coastguard Worker
3873*8975f5c5SAndroid Build Coastguard Worker int storageDepth = 0;
3874*8975f5c5SAndroid Build Coastguard Worker if (baseLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
3875*8975f5c5SAndroid Build Coastguard Worker {
3876*8975f5c5SAndroid Build Coastguard Worker storageDepth = getLayerCount(baseLevel);
3877*8975f5c5SAndroid Build Coastguard Worker }
3878*8975f5c5SAndroid Build Coastguard Worker
3879*8975f5c5SAndroid Build Coastguard Worker // Only reallocate the layers if the size doesn't match
3880*8975f5c5SAndroid Build Coastguard Worker if (size.depth != mLayerCounts[level])
3881*8975f5c5SAndroid Build Coastguard Worker {
3882*8975f5c5SAndroid Build Coastguard Worker for (int layer = 0; layer < mLayerCounts[level]; layer++)
3883*8975f5c5SAndroid Build Coastguard Worker {
3884*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mImageArray[level][layer]);
3885*8975f5c5SAndroid Build Coastguard Worker }
3886*8975f5c5SAndroid Build Coastguard Worker SafeDeleteArray(mImageArray[level]);
3887*8975f5c5SAndroid Build Coastguard Worker mLayerCounts[level] = size.depth;
3888*8975f5c5SAndroid Build Coastguard Worker
3889*8975f5c5SAndroid Build Coastguard Worker if (size.depth > 0)
3890*8975f5c5SAndroid Build Coastguard Worker {
3891*8975f5c5SAndroid Build Coastguard Worker mImageArray[level] = new ImageD3D *[size.depth];
3892*8975f5c5SAndroid Build Coastguard Worker for (int layer = 0; layer < mLayerCounts[level]; layer++)
3893*8975f5c5SAndroid Build Coastguard Worker {
3894*8975f5c5SAndroid Build Coastguard Worker mImageArray[level][layer] = mRenderer->createImage();
3895*8975f5c5SAndroid Build Coastguard Worker }
3896*8975f5c5SAndroid Build Coastguard Worker }
3897*8975f5c5SAndroid Build Coastguard Worker }
3898*8975f5c5SAndroid Build Coastguard Worker
3899*8975f5c5SAndroid Build Coastguard Worker if (mTexStorage)
3900*8975f5c5SAndroid Build Coastguard Worker {
3901*8975f5c5SAndroid Build Coastguard Worker const int storageLevels = mTexStorage->getLevelCount();
3902*8975f5c5SAndroid Build Coastguard Worker
3903*8975f5c5SAndroid Build Coastguard Worker if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
3904*8975f5c5SAndroid Build Coastguard Worker size.height != storageHeight || size.depth != storageDepth ||
3905*8975f5c5SAndroid Build Coastguard Worker internalformat != storageFormat) // Discard mismatched storage
3906*8975f5c5SAndroid Build Coastguard Worker {
3907*8975f5c5SAndroid Build Coastguard Worker markAllImagesDirty();
3908*8975f5c5SAndroid Build Coastguard Worker
3909*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask copyImageMask;
3910*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set();
3911*8975f5c5SAndroid Build Coastguard Worker copyImageMask.set(level, false);
3912*8975f5c5SAndroid Build Coastguard Worker
3913*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, copyImageMask));
3914*8975f5c5SAndroid Build Coastguard Worker }
3915*8975f5c5SAndroid Build Coastguard Worker }
3916*8975f5c5SAndroid Build Coastguard Worker
3917*8975f5c5SAndroid Build Coastguard Worker if (size.depth > 0)
3918*8975f5c5SAndroid Build Coastguard Worker {
3919*8975f5c5SAndroid Build Coastguard Worker for (int layer = 0; layer < mLayerCounts[level]; layer++)
3920*8975f5c5SAndroid Build Coastguard Worker {
3921*8975f5c5SAndroid Build Coastguard Worker mImageArray[level][layer]->redefine(gl::TextureType::_2DArray, internalformat,
3922*8975f5c5SAndroid Build Coastguard Worker gl::Extents(size.width, size.height, 1),
3923*8975f5c5SAndroid Build Coastguard Worker forceRelease);
3924*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = mDirtyImages || mImageArray[level][layer]->isDirty();
3925*8975f5c5SAndroid Build Coastguard Worker }
3926*8975f5c5SAndroid Build Coastguard Worker }
3927*8975f5c5SAndroid Build Coastguard Worker
3928*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3929*8975f5c5SAndroid Build Coastguard Worker }
3930*8975f5c5SAndroid Build Coastguard Worker
imageIterator() const3931*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const
3932*8975f5c5SAndroid Build Coastguard Worker {
3933*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndexIterator::Make2DArray(0, mTexStorage->getLevelCount(), mLayerCounts);
3934*8975f5c5SAndroid Build Coastguard Worker }
3935*8975f5c5SAndroid Build Coastguard Worker
getImageIndex(GLint mip,GLint layer) const3936*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex TextureD3D_2DArray::getImageIndex(GLint mip, GLint layer) const
3937*8975f5c5SAndroid Build Coastguard Worker {
3938*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndex::Make2DArray(mip, layer);
3939*8975f5c5SAndroid Build Coastguard Worker }
3940*8975f5c5SAndroid Build Coastguard Worker
isValidIndex(const gl::ImageIndex & index) const3941*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DArray::isValidIndex(const gl::ImageIndex &index) const
3942*8975f5c5SAndroid Build Coastguard Worker {
3943*8975f5c5SAndroid Build Coastguard Worker // Check for having a storage and the right type of index
3944*8975f5c5SAndroid Build Coastguard Worker if (!mTexStorage || index.getType() != gl::TextureType::_2DArray)
3945*8975f5c5SAndroid Build Coastguard Worker {
3946*8975f5c5SAndroid Build Coastguard Worker return false;
3947*8975f5c5SAndroid Build Coastguard Worker }
3948*8975f5c5SAndroid Build Coastguard Worker
3949*8975f5c5SAndroid Build Coastguard Worker // Check the mip index
3950*8975f5c5SAndroid Build Coastguard Worker if (index.getLevelIndex() < 0 || index.getLevelIndex() >= mTexStorage->getLevelCount())
3951*8975f5c5SAndroid Build Coastguard Worker {
3952*8975f5c5SAndroid Build Coastguard Worker return false;
3953*8975f5c5SAndroid Build Coastguard Worker }
3954*8975f5c5SAndroid Build Coastguard Worker
3955*8975f5c5SAndroid Build Coastguard Worker // Check the layer index
3956*8975f5c5SAndroid Build Coastguard Worker return (!index.hasLayer() || (index.getLayerIndex() >= 0 &&
3957*8975f5c5SAndroid Build Coastguard Worker index.getLayerIndex() < mLayerCounts[index.getLevelIndex()]));
3958*8975f5c5SAndroid Build Coastguard Worker }
3959*8975f5c5SAndroid Build Coastguard Worker
markAllImagesDirty()3960*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_2DArray::markAllImagesDirty()
3961*8975f5c5SAndroid Build Coastguard Worker {
3962*8975f5c5SAndroid Build Coastguard Worker for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++)
3963*8975f5c5SAndroid Build Coastguard Worker {
3964*8975f5c5SAndroid Build Coastguard Worker for (int dirtyLayer = 0; dirtyLayer < mLayerCounts[dirtyLevel]; dirtyLayer++)
3965*8975f5c5SAndroid Build Coastguard Worker {
3966*8975f5c5SAndroid Build Coastguard Worker mImageArray[dirtyLevel][dirtyLayer]->markDirty();
3967*8975f5c5SAndroid Build Coastguard Worker }
3968*8975f5c5SAndroid Build Coastguard Worker }
3969*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
3970*8975f5c5SAndroid Build Coastguard Worker }
3971*8975f5c5SAndroid Build Coastguard Worker
TextureD3DImmutableBase(const gl::TextureState & state,RendererD3D * renderer)3972*8975f5c5SAndroid Build Coastguard Worker TextureD3DImmutableBase::TextureD3DImmutableBase(const gl::TextureState &state,
3973*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer)
3974*8975f5c5SAndroid Build Coastguard Worker : TextureD3D(state, renderer)
3975*8975f5c5SAndroid Build Coastguard Worker {}
3976*8975f5c5SAndroid Build Coastguard Worker
~TextureD3DImmutableBase()3977*8975f5c5SAndroid Build Coastguard Worker TextureD3DImmutableBase::~TextureD3DImmutableBase() {}
3978*8975f5c5SAndroid Build Coastguard Worker
getImage(const gl::ImageIndex & index) const3979*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3DImmutableBase::getImage(const gl::ImageIndex &index) const
3980*8975f5c5SAndroid Build Coastguard Worker {
3981*8975f5c5SAndroid Build Coastguard Worker return nullptr;
3982*8975f5c5SAndroid Build Coastguard Worker }
3983*8975f5c5SAndroid Build Coastguard Worker
setImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)3984*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3DImmutableBase::setImage(const gl::Context *context,
3985*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
3986*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
3987*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
3988*8975f5c5SAndroid Build Coastguard Worker GLenum format,
3989*8975f5c5SAndroid Build Coastguard Worker GLenum type,
3990*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
3991*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
3992*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
3993*8975f5c5SAndroid Build Coastguard Worker {
3994*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
3995*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
3996*8975f5c5SAndroid Build Coastguard Worker }
3997*8975f5c5SAndroid Build Coastguard Worker
setSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)3998*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3DImmutableBase::setSubImage(const gl::Context *context,
3999*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4000*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
4001*8975f5c5SAndroid Build Coastguard Worker GLenum format,
4002*8975f5c5SAndroid Build Coastguard Worker GLenum type,
4003*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
4004*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
4005*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
4006*8975f5c5SAndroid Build Coastguard Worker {
4007*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4008*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4009*8975f5c5SAndroid Build Coastguard Worker }
4010*8975f5c5SAndroid Build Coastguard Worker
setCompressedImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)4011*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3DImmutableBase::setCompressedImage(const gl::Context *context,
4012*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4013*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
4014*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
4015*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
4016*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
4017*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
4018*8975f5c5SAndroid Build Coastguard Worker {
4019*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4020*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4021*8975f5c5SAndroid Build Coastguard Worker }
4022*8975f5c5SAndroid Build Coastguard Worker
setCompressedSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)4023*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3DImmutableBase::setCompressedSubImage(const gl::Context *context,
4024*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4025*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
4026*8975f5c5SAndroid Build Coastguard Worker GLenum format,
4027*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
4028*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
4029*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
4030*8975f5c5SAndroid Build Coastguard Worker {
4031*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4032*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4033*8975f5c5SAndroid Build Coastguard Worker }
4034*8975f5c5SAndroid Build Coastguard Worker
copyImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Rectangle & sourceArea,GLenum internalFormat,gl::Framebuffer * source)4035*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3DImmutableBase::copyImage(const gl::Context *context,
4036*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4037*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
4038*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
4039*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
4040*8975f5c5SAndroid Build Coastguard Worker {
4041*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4042*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4043*8975f5c5SAndroid Build Coastguard Worker }
4044*8975f5c5SAndroid Build Coastguard Worker
copySubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,const gl::Rectangle & sourceArea,gl::Framebuffer * source)4045*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3DImmutableBase::copySubImage(const gl::Context *context,
4046*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4047*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
4048*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
4049*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
4050*8975f5c5SAndroid Build Coastguard Worker {
4051*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4052*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4053*8975f5c5SAndroid Build Coastguard Worker }
4054*8975f5c5SAndroid Build Coastguard Worker
bindTexImage(const gl::Context * context,egl::Surface * surface)4055*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3DImmutableBase::bindTexImage(const gl::Context *context,
4056*8975f5c5SAndroid Build Coastguard Worker egl::Surface *surface)
4057*8975f5c5SAndroid Build Coastguard Worker {
4058*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4059*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4060*8975f5c5SAndroid Build Coastguard Worker }
4061*8975f5c5SAndroid Build Coastguard Worker
releaseTexImage(const gl::Context * context)4062*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3DImmutableBase::releaseTexImage(const gl::Context *context)
4063*8975f5c5SAndroid Build Coastguard Worker {
4064*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4065*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4066*8975f5c5SAndroid Build Coastguard Worker }
4067*8975f5c5SAndroid Build Coastguard Worker
TextureD3D_External(const gl::TextureState & state,RendererD3D * renderer)4068*8975f5c5SAndroid Build Coastguard Worker TextureD3D_External::TextureD3D_External(const gl::TextureState &state, RendererD3D *renderer)
4069*8975f5c5SAndroid Build Coastguard Worker : TextureD3DImmutableBase(state, renderer)
4070*8975f5c5SAndroid Build Coastguard Worker {}
4071*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D_External()4072*8975f5c5SAndroid Build Coastguard Worker TextureD3D_External::~TextureD3D_External() {}
4073*8975f5c5SAndroid Build Coastguard Worker
getLayerCount(int level) const4074*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_External::getLayerCount(int level) const
4075*8975f5c5SAndroid Build Coastguard Worker {
4076*8975f5c5SAndroid Build Coastguard Worker return 1;
4077*8975f5c5SAndroid Build Coastguard Worker }
4078*8975f5c5SAndroid Build Coastguard Worker
setImageExternal(const gl::Context * context,gl::TextureType type,egl::Stream * stream,const egl::Stream::GLTextureDescription & desc)4079*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_External::setImageExternal(const gl::Context *context,
4080*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
4081*8975f5c5SAndroid Build Coastguard Worker egl::Stream *stream,
4082*8975f5c5SAndroid Build Coastguard Worker const egl::Stream::GLTextureDescription &desc)
4083*8975f5c5SAndroid Build Coastguard Worker {
4084*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == gl::TextureType::External);
4085*8975f5c5SAndroid Build Coastguard Worker
4086*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
4087*8975f5c5SAndroid Build Coastguard Worker
4088*8975f5c5SAndroid Build Coastguard Worker // If the stream is null, the external image is unbound and we release the storage
4089*8975f5c5SAndroid Build Coastguard Worker if (stream != nullptr)
4090*8975f5c5SAndroid Build Coastguard Worker {
4091*8975f5c5SAndroid Build Coastguard Worker mTexStorage = mRenderer->createTextureStorageExternal(stream, desc, mState.getLabel());
4092*8975f5c5SAndroid Build Coastguard Worker }
4093*8975f5c5SAndroid Build Coastguard Worker
4094*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4095*8975f5c5SAndroid Build Coastguard Worker }
4096*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)4097*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_External::setEGLImageTarget(const gl::Context *context,
4098*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
4099*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
4100*8975f5c5SAndroid Build Coastguard Worker {
4101*8975f5c5SAndroid Build Coastguard Worker EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image);
4102*8975f5c5SAndroid Build Coastguard Worker
4103*8975f5c5SAndroid Build Coastguard Worker // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error.
4104*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D *renderTargetD3D = nullptr;
4105*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D));
4106*8975f5c5SAndroid Build Coastguard Worker
4107*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
4108*8975f5c5SAndroid Build Coastguard Worker mTexStorage =
4109*8975f5c5SAndroid Build Coastguard Worker mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D, mState.getLabel());
4110*8975f5c5SAndroid Build Coastguard Worker
4111*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4112*8975f5c5SAndroid Build Coastguard Worker }
4113*8975f5c5SAndroid Build Coastguard Worker
initMipmapImages(const gl::Context * context)4114*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_External::initMipmapImages(const gl::Context *context)
4115*8975f5c5SAndroid Build Coastguard Worker {
4116*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4117*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
4118*8975f5c5SAndroid Build Coastguard Worker }
4119*8975f5c5SAndroid Build Coastguard Worker
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)4120*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_External::getRenderTarget(const gl::Context *context,
4121*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4122*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
4123*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D **outRT)
4124*8975f5c5SAndroid Build Coastguard Worker {
4125*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4126*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
4127*8975f5c5SAndroid Build Coastguard Worker }
4128*8975f5c5SAndroid Build Coastguard Worker
isImageComplete(const gl::ImageIndex & index) const4129*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_External::isImageComplete(const gl::ImageIndex &index) const
4130*8975f5c5SAndroid Build Coastguard Worker {
4131*8975f5c5SAndroid Build Coastguard Worker return (index.getLevelIndex() == 0) ? (mTexStorage != nullptr) : false;
4132*8975f5c5SAndroid Build Coastguard Worker }
4133*8975f5c5SAndroid Build Coastguard Worker
initializeStorage(const gl::Context * context,BindFlags bindFlags)4134*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_External::initializeStorage(const gl::Context *context,
4135*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags)
4136*8975f5c5SAndroid Build Coastguard Worker {
4137*8975f5c5SAndroid Build Coastguard Worker // Texture storage is created when an external image is bound
4138*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
4139*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4140*8975f5c5SAndroid Build Coastguard Worker }
4141*8975f5c5SAndroid Build Coastguard Worker
createCompleteStorage(const gl::Context * context,BindFlags bindFlags,TexStoragePointer * outStorage) const4142*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_External::createCompleteStorage(const gl::Context *context,
4143*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags,
4144*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer *outStorage) const
4145*8975f5c5SAndroid Build Coastguard Worker {
4146*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4147*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4148*8975f5c5SAndroid Build Coastguard Worker }
4149*8975f5c5SAndroid Build Coastguard Worker
setCompleteTexStorage(const gl::Context * context,TextureStorage * newCompleteTexStorage)4150*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_External::setCompleteTexStorage(const gl::Context *context,
4151*8975f5c5SAndroid Build Coastguard Worker TextureStorage *newCompleteTexStorage)
4152*8975f5c5SAndroid Build Coastguard Worker {
4153*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4154*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4155*8975f5c5SAndroid Build Coastguard Worker }
4156*8975f5c5SAndroid Build Coastguard Worker
updateStorage(const gl::Context * context)4157*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_External::updateStorage(const gl::Context *context)
4158*8975f5c5SAndroid Build Coastguard Worker {
4159*8975f5c5SAndroid Build Coastguard Worker // Texture storage does not need to be updated since it is already loaded with the latest
4160*8975f5c5SAndroid Build Coastguard Worker // external image
4161*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
4162*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4163*8975f5c5SAndroid Build Coastguard Worker }
4164*8975f5c5SAndroid Build Coastguard Worker
imageIterator() const4165*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator TextureD3D_External::imageIterator() const
4166*8975f5c5SAndroid Build Coastguard Worker {
4167*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
4168*8975f5c5SAndroid Build Coastguard Worker }
4169*8975f5c5SAndroid Build Coastguard Worker
getImageIndex(GLint mip,GLint) const4170*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex TextureD3D_External::getImageIndex(GLint mip, GLint /*layer*/) const
4171*8975f5c5SAndroid Build Coastguard Worker {
4172*8975f5c5SAndroid Build Coastguard Worker // "layer" does not apply to 2D Textures.
4173*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndex::Make2D(mip);
4174*8975f5c5SAndroid Build Coastguard Worker }
4175*8975f5c5SAndroid Build Coastguard Worker
isValidIndex(const gl::ImageIndex & index) const4176*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_External::isValidIndex(const gl::ImageIndex &index) const
4177*8975f5c5SAndroid Build Coastguard Worker {
4178*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage && index.getType() == gl::TextureType::External &&
4179*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex() == 0);
4180*8975f5c5SAndroid Build Coastguard Worker }
4181*8975f5c5SAndroid Build Coastguard Worker
markAllImagesDirty()4182*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_External::markAllImagesDirty()
4183*8975f5c5SAndroid Build Coastguard Worker {
4184*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4185*8975f5c5SAndroid Build Coastguard Worker }
4186*8975f5c5SAndroid Build Coastguard Worker
TextureD3D_2DMultisample(const gl::TextureState & state,RendererD3D * renderer)4187*8975f5c5SAndroid Build Coastguard Worker TextureD3D_2DMultisample::TextureD3D_2DMultisample(const gl::TextureState &state,
4188*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer)
4189*8975f5c5SAndroid Build Coastguard Worker : TextureD3DImmutableBase(state, renderer)
4190*8975f5c5SAndroid Build Coastguard Worker {}
4191*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D_2DMultisample()4192*8975f5c5SAndroid Build Coastguard Worker TextureD3D_2DMultisample::~TextureD3D_2DMultisample() {}
4193*8975f5c5SAndroid Build Coastguard Worker
setStorageMultisample(const gl::Context * context,gl::TextureType type,GLsizei samples,GLint internalformat,const gl::Extents & size,bool fixedSampleLocations)4194*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisample::setStorageMultisample(const gl::Context *context,
4195*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
4196*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
4197*8975f5c5SAndroid Build Coastguard Worker GLint internalformat,
4198*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
4199*8975f5c5SAndroid Build Coastguard Worker bool fixedSampleLocations)
4200*8975f5c5SAndroid Build Coastguard Worker {
4201*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == gl::TextureType::_2DMultisample && size.depth == 1);
4202*8975f5c5SAndroid Build Coastguard Worker
4203*8975f5c5SAndroid Build Coastguard Worker // We allocate storage immediately instead of doing it lazily like other TextureD3D classes do.
4204*8975f5c5SAndroid Build Coastguard Worker // This requires less state in this class.
4205*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage = {mRenderer->createTextureStorage2DMultisample(
4206*8975f5c5SAndroid Build Coastguard Worker internalformat, size.width, size.height, static_cast<int>(0),
4207*8975f5c5SAndroid Build Coastguard Worker samples, fixedSampleLocations, mState.getLabel()),
4208*8975f5c5SAndroid Build Coastguard Worker context};
4209*8975f5c5SAndroid Build Coastguard Worker
4210*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
4211*8975f5c5SAndroid Build Coastguard Worker storage.release();
4212*8975f5c5SAndroid Build Coastguard Worker
4213*8975f5c5SAndroid Build Coastguard Worker mImmutable = true;
4214*8975f5c5SAndroid Build Coastguard Worker
4215*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4216*8975f5c5SAndroid Build Coastguard Worker }
4217*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)4218*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisample::setEGLImageTarget(const gl::Context *context,
4219*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
4220*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
4221*8975f5c5SAndroid Build Coastguard Worker {
4222*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4223*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4224*8975f5c5SAndroid Build Coastguard Worker }
4225*8975f5c5SAndroid Build Coastguard Worker
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)4226*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisample::getRenderTarget(const gl::Context *context,
4227*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4228*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
4229*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D **outRT)
4230*8975f5c5SAndroid Build Coastguard Worker {
4231*8975f5c5SAndroid Build Coastguard Worker ASSERT(!index.hasLayer());
4232*8975f5c5SAndroid Build Coastguard Worker
4233*8975f5c5SAndroid Build Coastguard Worker // ensure the underlying texture is created
4234*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
4235*8975f5c5SAndroid Build Coastguard Worker
4236*8975f5c5SAndroid Build Coastguard Worker return mTexStorage->getRenderTarget(context, index, samples, outRT);
4237*8975f5c5SAndroid Build Coastguard Worker }
4238*8975f5c5SAndroid Build Coastguard Worker
imageIterator() const4239*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator TextureD3D_2DMultisample::imageIterator() const
4240*8975f5c5SAndroid Build Coastguard Worker {
4241*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndexIterator::Make2DMultisample();
4242*8975f5c5SAndroid Build Coastguard Worker }
4243*8975f5c5SAndroid Build Coastguard Worker
getImageIndex(GLint mip,GLint layer) const4244*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex TextureD3D_2DMultisample::getImageIndex(GLint mip, GLint layer) const
4245*8975f5c5SAndroid Build Coastguard Worker {
4246*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndex::Make2DMultisample();
4247*8975f5c5SAndroid Build Coastguard Worker }
4248*8975f5c5SAndroid Build Coastguard Worker
isValidIndex(const gl::ImageIndex & index) const4249*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DMultisample::isValidIndex(const gl::ImageIndex &index) const
4250*8975f5c5SAndroid Build Coastguard Worker {
4251*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage && index.getType() == gl::TextureType::_2DMultisample &&
4252*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex() == 0);
4253*8975f5c5SAndroid Build Coastguard Worker }
4254*8975f5c5SAndroid Build Coastguard Worker
getLayerCount(int level) const4255*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_2DMultisample::getLayerCount(int level) const
4256*8975f5c5SAndroid Build Coastguard Worker {
4257*8975f5c5SAndroid Build Coastguard Worker return 1;
4258*8975f5c5SAndroid Build Coastguard Worker }
4259*8975f5c5SAndroid Build Coastguard Worker
markAllImagesDirty()4260*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_2DMultisample::markAllImagesDirty() {}
4261*8975f5c5SAndroid Build Coastguard Worker
initializeStorage(const gl::Context * context,BindFlags bindFlags)4262*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisample::initializeStorage(const gl::Context *context,
4263*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags)
4264*8975f5c5SAndroid Build Coastguard Worker {
4265*8975f5c5SAndroid Build Coastguard Worker // initializeStorage should only be called in a situation where the texture already has storage
4266*8975f5c5SAndroid Build Coastguard Worker // associated with it (storage is created in setStorageMultisample).
4267*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
4268*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4269*8975f5c5SAndroid Build Coastguard Worker }
4270*8975f5c5SAndroid Build Coastguard Worker
createCompleteStorage(const gl::Context * context,BindFlags bindFlags,TexStoragePointer * outStorage) const4271*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisample::createCompleteStorage(const gl::Context *context,
4272*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags,
4273*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer *outStorage) const
4274*8975f5c5SAndroid Build Coastguard Worker {
4275*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4276*8975f5c5SAndroid Build Coastguard Worker *outStorage = {mTexStorage, context};
4277*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4278*8975f5c5SAndroid Build Coastguard Worker }
4279*8975f5c5SAndroid Build Coastguard Worker
setCompleteTexStorage(const gl::Context * context,TextureStorage * newCompleteTexStorage)4280*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisample::setCompleteTexStorage(const gl::Context *context,
4281*8975f5c5SAndroid Build Coastguard Worker TextureStorage *newCompleteTexStorage)
4282*8975f5c5SAndroid Build Coastguard Worker {
4283*8975f5c5SAndroid Build Coastguard Worker // These textures are immutable, so this should only be ever called once.
4284*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mTexStorage);
4285*8975f5c5SAndroid Build Coastguard Worker mTexStorage = newCompleteTexStorage;
4286*8975f5c5SAndroid Build Coastguard Worker mTexStorageObserverBinding.bind(mTexStorage);
4287*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4288*8975f5c5SAndroid Build Coastguard Worker }
4289*8975f5c5SAndroid Build Coastguard Worker
updateStorage(const gl::Context * context)4290*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisample::updateStorage(const gl::Context *context)
4291*8975f5c5SAndroid Build Coastguard Worker {
4292*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4293*8975f5c5SAndroid Build Coastguard Worker }
4294*8975f5c5SAndroid Build Coastguard Worker
initMipmapImages(const gl::Context * context)4295*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisample::initMipmapImages(const gl::Context *context)
4296*8975f5c5SAndroid Build Coastguard Worker {
4297*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4298*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4299*8975f5c5SAndroid Build Coastguard Worker }
4300*8975f5c5SAndroid Build Coastguard Worker
isImageComplete(const gl::ImageIndex & index) const4301*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DMultisample::isImageComplete(const gl::ImageIndex &index) const
4302*8975f5c5SAndroid Build Coastguard Worker {
4303*8975f5c5SAndroid Build Coastguard Worker return true;
4304*8975f5c5SAndroid Build Coastguard Worker }
4305*8975f5c5SAndroid Build Coastguard Worker
TextureD3D_2DMultisampleArray(const gl::TextureState & state,RendererD3D * renderer)4306*8975f5c5SAndroid Build Coastguard Worker TextureD3D_2DMultisampleArray::TextureD3D_2DMultisampleArray(const gl::TextureState &state,
4307*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer)
4308*8975f5c5SAndroid Build Coastguard Worker : TextureD3DImmutableBase(state, renderer)
4309*8975f5c5SAndroid Build Coastguard Worker {}
4310*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D_2DMultisampleArray()4311*8975f5c5SAndroid Build Coastguard Worker TextureD3D_2DMultisampleArray::~TextureD3D_2DMultisampleArray() {}
4312*8975f5c5SAndroid Build Coastguard Worker
setStorageMultisample(const gl::Context * context,gl::TextureType type,GLsizei samples,GLint internalformat,const gl::Extents & size,bool fixedSampleLocations)4313*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisampleArray::setStorageMultisample(const gl::Context *context,
4314*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
4315*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
4316*8975f5c5SAndroid Build Coastguard Worker GLint internalformat,
4317*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
4318*8975f5c5SAndroid Build Coastguard Worker bool fixedSampleLocations)
4319*8975f5c5SAndroid Build Coastguard Worker {
4320*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == gl::TextureType::_2DMultisampleArray);
4321*8975f5c5SAndroid Build Coastguard Worker
4322*8975f5c5SAndroid Build Coastguard Worker mLayerCount = size.depth;
4323*8975f5c5SAndroid Build Coastguard Worker
4324*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage = {
4325*8975f5c5SAndroid Build Coastguard Worker mRenderer->createTextureStorage2DMultisampleArray(internalformat, size.width, size.height,
4326*8975f5c5SAndroid Build Coastguard Worker size.depth, static_cast<int>(0), samples,
4327*8975f5c5SAndroid Build Coastguard Worker fixedSampleLocations, mState.getLabel()),
4328*8975f5c5SAndroid Build Coastguard Worker context};
4329*8975f5c5SAndroid Build Coastguard Worker
4330*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
4331*8975f5c5SAndroid Build Coastguard Worker storage.release();
4332*8975f5c5SAndroid Build Coastguard Worker
4333*8975f5c5SAndroid Build Coastguard Worker mImmutable = true;
4334*8975f5c5SAndroid Build Coastguard Worker
4335*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4336*8975f5c5SAndroid Build Coastguard Worker }
4337*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)4338*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisampleArray::setEGLImageTarget(const gl::Context *context,
4339*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
4340*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
4341*8975f5c5SAndroid Build Coastguard Worker {
4342*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4343*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4344*8975f5c5SAndroid Build Coastguard Worker }
4345*8975f5c5SAndroid Build Coastguard Worker
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)4346*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisampleArray::getRenderTarget(const gl::Context *context,
4347*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4348*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
4349*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D **outRT)
4350*8975f5c5SAndroid Build Coastguard Worker {
4351*8975f5c5SAndroid Build Coastguard Worker // ensure the underlying texture is created
4352*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureRenderTarget(context));
4353*8975f5c5SAndroid Build Coastguard Worker
4354*8975f5c5SAndroid Build Coastguard Worker return mTexStorage->getRenderTarget(context, index, samples, outRT);
4355*8975f5c5SAndroid Build Coastguard Worker }
4356*8975f5c5SAndroid Build Coastguard Worker
imageIterator() const4357*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator TextureD3D_2DMultisampleArray::imageIterator() const
4358*8975f5c5SAndroid Build Coastguard Worker {
4359*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndexIterator::Make2DMultisampleArray(&mLayerCount);
4360*8975f5c5SAndroid Build Coastguard Worker }
4361*8975f5c5SAndroid Build Coastguard Worker
getImageIndex(GLint mip,GLint layer) const4362*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex TextureD3D_2DMultisampleArray::getImageIndex(GLint mip, GLint layer) const
4363*8975f5c5SAndroid Build Coastguard Worker {
4364*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndex::Make2DMultisampleArray(layer);
4365*8975f5c5SAndroid Build Coastguard Worker }
4366*8975f5c5SAndroid Build Coastguard Worker
isValidIndex(const gl::ImageIndex & index) const4367*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DMultisampleArray::isValidIndex(const gl::ImageIndex &index) const
4368*8975f5c5SAndroid Build Coastguard Worker {
4369*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage && index.getType() == gl::TextureType::_2DMultisampleArray &&
4370*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex() == 0);
4371*8975f5c5SAndroid Build Coastguard Worker }
4372*8975f5c5SAndroid Build Coastguard Worker
getLayerCount(int level) const4373*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_2DMultisampleArray::getLayerCount(int level) const
4374*8975f5c5SAndroid Build Coastguard Worker {
4375*8975f5c5SAndroid Build Coastguard Worker return mLayerCount;
4376*8975f5c5SAndroid Build Coastguard Worker }
4377*8975f5c5SAndroid Build Coastguard Worker
markAllImagesDirty()4378*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_2DMultisampleArray::markAllImagesDirty() {}
4379*8975f5c5SAndroid Build Coastguard Worker
initializeStorage(const gl::Context * context,BindFlags bindFlags)4380*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisampleArray::initializeStorage(const gl::Context *context,
4381*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags)
4382*8975f5c5SAndroid Build Coastguard Worker {
4383*8975f5c5SAndroid Build Coastguard Worker // initializeStorage should only be called in a situation where the texture already has storage
4384*8975f5c5SAndroid Build Coastguard Worker // associated with it (storage is created in setStorageMultisample).
4385*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
4386*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4387*8975f5c5SAndroid Build Coastguard Worker }
4388*8975f5c5SAndroid Build Coastguard Worker
createCompleteStorage(const gl::Context * context,BindFlags bindFlags,TexStoragePointer * outStorage) const4389*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisampleArray::createCompleteStorage(
4390*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
4391*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags,
4392*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer *outStorage) const
4393*8975f5c5SAndroid Build Coastguard Worker {
4394*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4395*8975f5c5SAndroid Build Coastguard Worker *outStorage = {mTexStorage, context};
4396*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4397*8975f5c5SAndroid Build Coastguard Worker }
4398*8975f5c5SAndroid Build Coastguard Worker
setCompleteTexStorage(const gl::Context * context,TextureStorage * newCompleteTexStorage)4399*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisampleArray::setCompleteTexStorage(
4400*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
4401*8975f5c5SAndroid Build Coastguard Worker TextureStorage *newCompleteTexStorage)
4402*8975f5c5SAndroid Build Coastguard Worker {
4403*8975f5c5SAndroid Build Coastguard Worker // These textures are immutable, so this should only be ever called once.
4404*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mTexStorage);
4405*8975f5c5SAndroid Build Coastguard Worker mTexStorage = newCompleteTexStorage;
4406*8975f5c5SAndroid Build Coastguard Worker mTexStorageObserverBinding.bind(mTexStorage);
4407*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4408*8975f5c5SAndroid Build Coastguard Worker }
4409*8975f5c5SAndroid Build Coastguard Worker
updateStorage(const gl::Context * context)4410*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisampleArray::updateStorage(const gl::Context *context)
4411*8975f5c5SAndroid Build Coastguard Worker {
4412*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4413*8975f5c5SAndroid Build Coastguard Worker }
4414*8975f5c5SAndroid Build Coastguard Worker
initMipmapImages(const gl::Context * context)4415*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_2DMultisampleArray::initMipmapImages(const gl::Context *context)
4416*8975f5c5SAndroid Build Coastguard Worker {
4417*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
4418*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4419*8975f5c5SAndroid Build Coastguard Worker }
4420*8975f5c5SAndroid Build Coastguard Worker
isImageComplete(const gl::ImageIndex & index) const4421*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_2DMultisampleArray::isImageComplete(const gl::ImageIndex &index) const
4422*8975f5c5SAndroid Build Coastguard Worker {
4423*8975f5c5SAndroid Build Coastguard Worker return true;
4424*8975f5c5SAndroid Build Coastguard Worker }
4425*8975f5c5SAndroid Build Coastguard Worker
TextureD3D_Buffer(const gl::TextureState & state,RendererD3D * renderer)4426*8975f5c5SAndroid Build Coastguard Worker TextureD3D_Buffer::TextureD3D_Buffer(const gl::TextureState &state, RendererD3D *renderer)
4427*8975f5c5SAndroid Build Coastguard Worker : TextureD3D(state, renderer), mInternalFormat(GL_INVALID_ENUM)
4428*8975f5c5SAndroid Build Coastguard Worker {}
4429*8975f5c5SAndroid Build Coastguard Worker
~TextureD3D_Buffer()4430*8975f5c5SAndroid Build Coastguard Worker TextureD3D_Buffer::~TextureD3D_Buffer() {}
4431*8975f5c5SAndroid Build Coastguard Worker
setImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)4432*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::setImage(const gl::Context *context,
4433*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4434*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
4435*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
4436*8975f5c5SAndroid Build Coastguard Worker GLenum format,
4437*8975f5c5SAndroid Build Coastguard Worker GLenum type,
4438*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
4439*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
4440*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
4441*8975f5c5SAndroid Build Coastguard Worker {
4442*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4443*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4444*8975f5c5SAndroid Build Coastguard Worker }
4445*8975f5c5SAndroid Build Coastguard Worker
setSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)4446*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::setSubImage(const gl::Context *context,
4447*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4448*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
4449*8975f5c5SAndroid Build Coastguard Worker GLenum format,
4450*8975f5c5SAndroid Build Coastguard Worker GLenum type,
4451*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
4452*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
4453*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
4454*8975f5c5SAndroid Build Coastguard Worker {
4455*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4456*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4457*8975f5c5SAndroid Build Coastguard Worker }
4458*8975f5c5SAndroid Build Coastguard Worker
setCompressedImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)4459*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::setCompressedImage(const gl::Context *context,
4460*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4461*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
4462*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
4463*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
4464*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
4465*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
4466*8975f5c5SAndroid Build Coastguard Worker {
4467*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4468*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4469*8975f5c5SAndroid Build Coastguard Worker }
4470*8975f5c5SAndroid Build Coastguard Worker
setCompressedSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)4471*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::setCompressedSubImage(const gl::Context *context,
4472*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4473*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
4474*8975f5c5SAndroid Build Coastguard Worker GLenum format,
4475*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
4476*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
4477*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
4478*8975f5c5SAndroid Build Coastguard Worker {
4479*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4480*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4481*8975f5c5SAndroid Build Coastguard Worker }
4482*8975f5c5SAndroid Build Coastguard Worker
copyImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Rectangle & sourceArea,GLenum internalFormat,gl::Framebuffer * source)4483*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::copyImage(const gl::Context *context,
4484*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4485*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
4486*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
4487*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
4488*8975f5c5SAndroid Build Coastguard Worker {
4489*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4490*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4491*8975f5c5SAndroid Build Coastguard Worker }
4492*8975f5c5SAndroid Build Coastguard Worker
copySubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,const gl::Rectangle & sourceArea,gl::Framebuffer * source)4493*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::copySubImage(const gl::Context *context,
4494*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4495*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
4496*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
4497*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
4498*8975f5c5SAndroid Build Coastguard Worker {
4499*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4500*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4501*8975f5c5SAndroid Build Coastguard Worker }
4502*8975f5c5SAndroid Build Coastguard Worker
bindTexImage(const gl::Context * context,egl::Surface * surface)4503*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::bindTexImage(const gl::Context *context, egl::Surface *surface)
4504*8975f5c5SAndroid Build Coastguard Worker {
4505*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4506*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4507*8975f5c5SAndroid Build Coastguard Worker }
4508*8975f5c5SAndroid Build Coastguard Worker
releaseTexImage(const gl::Context * context)4509*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::releaseTexImage(const gl::Context *context)
4510*8975f5c5SAndroid Build Coastguard Worker {
4511*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4512*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4513*8975f5c5SAndroid Build Coastguard Worker }
4514*8975f5c5SAndroid Build Coastguard Worker
getLayerCount(int level) const4515*8975f5c5SAndroid Build Coastguard Worker GLsizei TextureD3D_Buffer::getLayerCount(int level) const
4516*8975f5c5SAndroid Build Coastguard Worker {
4517*8975f5c5SAndroid Build Coastguard Worker return 1;
4518*8975f5c5SAndroid Build Coastguard Worker }
4519*8975f5c5SAndroid Build Coastguard Worker
initMipmapImages(const gl::Context * context)4520*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::initMipmapImages(const gl::Context *context)
4521*8975f5c5SAndroid Build Coastguard Worker {
4522*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4523*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
4524*8975f5c5SAndroid Build Coastguard Worker }
4525*8975f5c5SAndroid Build Coastguard Worker
isImageComplete(const gl::ImageIndex & index) const4526*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Buffer::isImageComplete(const gl::ImageIndex &index) const
4527*8975f5c5SAndroid Build Coastguard Worker {
4528*8975f5c5SAndroid Build Coastguard Worker return (index.getLevelIndex() == 0) ? (mTexStorage != nullptr) : false;
4529*8975f5c5SAndroid Build Coastguard Worker }
4530*8975f5c5SAndroid Build Coastguard Worker
initializeStorage(const gl::Context * context,BindFlags bindFlags)4531*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::initializeStorage(const gl::Context *context, BindFlags bindFlags)
4532*8975f5c5SAndroid Build Coastguard Worker {
4533*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
4534*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4535*8975f5c5SAndroid Build Coastguard Worker }
4536*8975f5c5SAndroid Build Coastguard Worker
createCompleteStorage(const gl::Context * context,BindFlags bindFlags,TexStoragePointer * outStorage) const4537*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::createCompleteStorage(const gl::Context *context,
4538*8975f5c5SAndroid Build Coastguard Worker BindFlags bindFlags,
4539*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer *outStorage) const
4540*8975f5c5SAndroid Build Coastguard Worker {
4541*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4542*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4543*8975f5c5SAndroid Build Coastguard Worker }
4544*8975f5c5SAndroid Build Coastguard Worker
setCompleteTexStorage(const gl::Context * context,TextureStorage * newCompleteTexStorage)4545*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::setCompleteTexStorage(const gl::Context *context,
4546*8975f5c5SAndroid Build Coastguard Worker TextureStorage *newCompleteTexStorage)
4547*8975f5c5SAndroid Build Coastguard Worker {
4548*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
4549*8975f5c5SAndroid Build Coastguard Worker mTexStorage = newCompleteTexStorage;
4550*8975f5c5SAndroid Build Coastguard Worker mTexStorageObserverBinding.bind(mTexStorage);
4551*8975f5c5SAndroid Build Coastguard Worker
4552*8975f5c5SAndroid Build Coastguard Worker mDirtyImages = true;
4553*8975f5c5SAndroid Build Coastguard Worker
4554*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4555*8975f5c5SAndroid Build Coastguard Worker }
4556*8975f5c5SAndroid Build Coastguard Worker
updateStorage(const gl::Context * context)4557*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::updateStorage(const gl::Context *context)
4558*8975f5c5SAndroid Build Coastguard Worker {
4559*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTexStorage);
4560*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4561*8975f5c5SAndroid Build Coastguard Worker }
4562*8975f5c5SAndroid Build Coastguard Worker
imageIterator() const4563*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndexIterator TextureD3D_Buffer::imageIterator() const
4564*8975f5c5SAndroid Build Coastguard Worker {
4565*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndexIterator::MakeBuffer();
4566*8975f5c5SAndroid Build Coastguard Worker }
4567*8975f5c5SAndroid Build Coastguard Worker
getImageIndex(GLint mip,GLint layer) const4568*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex TextureD3D_Buffer::getImageIndex(GLint mip, GLint layer) const
4569*8975f5c5SAndroid Build Coastguard Worker {
4570*8975f5c5SAndroid Build Coastguard Worker return gl::ImageIndex::MakeBuffer();
4571*8975f5c5SAndroid Build Coastguard Worker }
4572*8975f5c5SAndroid Build Coastguard Worker
isValidIndex(const gl::ImageIndex & index) const4573*8975f5c5SAndroid Build Coastguard Worker bool TextureD3D_Buffer::isValidIndex(const gl::ImageIndex &index) const
4574*8975f5c5SAndroid Build Coastguard Worker {
4575*8975f5c5SAndroid Build Coastguard Worker return (mTexStorage && index.getType() == gl::TextureType::Buffer &&
4576*8975f5c5SAndroid Build Coastguard Worker index.getLevelIndex() == 0);
4577*8975f5c5SAndroid Build Coastguard Worker }
4578*8975f5c5SAndroid Build Coastguard Worker
markAllImagesDirty()4579*8975f5c5SAndroid Build Coastguard Worker void TextureD3D_Buffer::markAllImagesDirty()
4580*8975f5c5SAndroid Build Coastguard Worker {
4581*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4582*8975f5c5SAndroid Build Coastguard Worker }
4583*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)4584*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::setEGLImageTarget(const gl::Context *context,
4585*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
4586*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
4587*8975f5c5SAndroid Build Coastguard Worker {
4588*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4589*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4590*8975f5c5SAndroid Build Coastguard Worker }
4591*8975f5c5SAndroid Build Coastguard Worker
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)4592*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::getRenderTarget(const gl::Context *context,
4593*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
4594*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
4595*8975f5c5SAndroid Build Coastguard Worker RenderTargetD3D **outRT)
4596*8975f5c5SAndroid Build Coastguard Worker {
4597*8975f5c5SAndroid Build Coastguard Worker ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
4598*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4599*8975f5c5SAndroid Build Coastguard Worker }
4600*8975f5c5SAndroid Build Coastguard Worker
getImage(const gl::ImageIndex & index) const4601*8975f5c5SAndroid Build Coastguard Worker ImageD3D *TextureD3D_Buffer::getImage(const gl::ImageIndex &index) const
4602*8975f5c5SAndroid Build Coastguard Worker {
4603*8975f5c5SAndroid Build Coastguard Worker return nullptr;
4604*8975f5c5SAndroid Build Coastguard Worker }
4605*8975f5c5SAndroid Build Coastguard Worker
setBuffer(const gl::Context * context,GLenum internalFormat)4606*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::setBuffer(const gl::Context *context, GLenum internalFormat)
4607*8975f5c5SAndroid Build Coastguard Worker {
4608*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.getType() == gl::TextureType::Buffer);
4609*8975f5c5SAndroid Build Coastguard Worker TexStoragePointer storage;
4610*8975f5c5SAndroid Build Coastguard Worker storage.reset(mRenderer->createTextureStorageBuffer(mState.getBuffer(), internalFormat,
4611*8975f5c5SAndroid Build Coastguard Worker mState.getLabel()));
4612*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
4613*8975f5c5SAndroid Build Coastguard Worker storage.release();
4614*8975f5c5SAndroid Build Coastguard Worker mInternalFormat = internalFormat;
4615*8975f5c5SAndroid Build Coastguard Worker mImmutable = false;
4616*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4617*8975f5c5SAndroid Build Coastguard Worker }
4618*8975f5c5SAndroid Build Coastguard Worker
syncState(const gl::Context * context,const gl::Texture::DirtyBits & dirtyBits,gl::Command source)4619*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureD3D_Buffer::syncState(const gl::Context *context,
4620*8975f5c5SAndroid Build Coastguard Worker const gl::Texture::DirtyBits &dirtyBits,
4621*8975f5c5SAndroid Build Coastguard Worker gl::Command source)
4622*8975f5c5SAndroid Build Coastguard Worker {
4623*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.getType() == gl::TextureType::Buffer);
4624*8975f5c5SAndroid Build Coastguard Worker if (dirtyBits.test(gl::Texture::DirtyBitType::DIRTY_BIT_IMPLEMENTATION) &&
4625*8975f5c5SAndroid Build Coastguard Worker mState.getBuffer().get() != nullptr)
4626*8975f5c5SAndroid Build Coastguard Worker {
4627*8975f5c5SAndroid Build Coastguard Worker // buffer data have been changed. Buffer data may out of sync
4628*8975f5c5SAndroid Build Coastguard Worker // give up the old TexStorage, create a new one.
4629*8975f5c5SAndroid Build Coastguard Worker // this may not efficient, since staging buffer may be patially updated.
4630*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setBuffer(context, mInternalFormat));
4631*8975f5c5SAndroid Build Coastguard Worker }
4632*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
4633*8975f5c5SAndroid Build Coastguard Worker }
4634*8975f5c5SAndroid Build Coastguard Worker
4635*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
4636