Hash :
e7d27705
Author :
Date :
2020-04-30T05:50:21
Fix corruption when changing the base level of a framebuffer texture attachment In the D3D renderer, changing the base level may trigger re-allocation of the texture storage, for example if the new base level has a different aspect ratio. During the process, image contents in the texture storage should be backed up properly. The D3D11 backend does this if an image has been associated with the texture storage, but it may happen such an association has never been established, and corruption will be observed then. The proposed patch mitigates the problem by introducing a new method named findRenderTarget(), with which one can tell if a mip level has been used as the render target. This works based on the fact that render targets are cached in the texture storage object. Hence all mip levels of interest can be found, without relying on the association between images and texture storage. Bug: angleproject:2291 Change-Id: Ic73af7b603be25c65760928f276bec16df003baf Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2158830 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
//
// Copyright 2002 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// TextureStorage.h: Defines the abstract rx::TextureStorage class.
#ifndef LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
#define LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
#include "common/debug.h"
#include "libANGLE/angletypes.h"
#include <GLES2/gl2.h>
#include <stdint.h>
namespace gl
{
class Context;
class ImageIndex;
struct Box;
struct PixelUnpackState;
} // namespace gl
namespace angle
{
class Subject;
} // namespace angle
namespace rx
{
class SwapChainD3D;
class RenderTargetD3D;
class ImageD3D;
// Dirty bit messages from TextureStorage
constexpr size_t kTextureStorageObserverMessageIndex = 0;
class TextureStorage : public angle::Subject
{
public:
TextureStorage() {}
~TextureStorage() override {}
virtual angle::Result onDestroy(const gl::Context *context);
virtual int getTopLevel() const = 0;
virtual bool isRenderTarget() const = 0;
virtual bool isManaged() const = 0;
virtual bool supportsNativeMipmapFunction() const = 0;
virtual int getLevelCount() const = 0;
virtual angle::Result findRenderTarget(const gl::Context *context,
const gl::ImageIndex &index,
GLsizei samples,
RenderTargetD3D **outRT) const = 0;
virtual angle::Result getRenderTarget(const gl::Context *context,
const gl::ImageIndex &index,
GLsizei samples,
RenderTargetD3D **outRT) = 0;
virtual angle::Result generateMipmap(const gl::Context *context,
const gl::ImageIndex &sourceIndex,
const gl::ImageIndex &destIndex) = 0;
virtual angle::Result copyToStorage(const gl::Context *context,
TextureStorage *destStorage) = 0;
virtual angle::Result setData(const gl::Context *context,
const gl::ImageIndex &index,
ImageD3D *image,
const gl::Box *destBox,
GLenum type,
const gl::PixelUnpackState &unpack,
const uint8_t *pixelData) = 0;
// This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D)
// might override it.
virtual angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
bool useLevelZeroTexture);
virtual void invalidateTextures() {}
// RenderToTexture methods
virtual angle::Result releaseMultisampledTexStorageForLevel(size_t level);
virtual angle::Result resolveTexture(const gl::Context *context);
virtual GLsizei getRenderToTextureSamples() const;
protected:
const angle::Subject *mSubject;
};
inline angle::Result TextureStorage::onDestroy(const gl::Context *context)
{
return angle::Result::Continue;
}
inline angle::Result TextureStorage::useLevelZeroWorkaroundTexture(const gl::Context *context,
bool useLevelZeroTexture)
{
return angle::Result::Continue;
}
inline angle::Result TextureStorage::releaseMultisampledTexStorageForLevel(size_t level)
{
return angle::Result::Continue;
}
inline angle::Result TextureStorage::resolveTexture(const gl::Context *context)
{
return angle::Result::Continue;
}
inline GLsizei TextureStorage::getRenderToTextureSamples() const
{
return 0;
}
using TexStoragePointer = angle::UniqueObjectPointer<TextureStorage, gl::Context>;
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_