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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
//
// Copyright 2012 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.
//
// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived
// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
// D3D9 texture.
#ifndef LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
#define LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
#include "common/debug.h"
#include "libANGLE/renderer/d3d/TextureStorage.h"
namespace rx
{
class EGLImageD3D;
class Renderer9;
class SwapChain9;
class RenderTargetD3D;
class RenderTarget9;
class TextureStorage9 : public TextureStorage
{
public:
~TextureStorage9() override;
static DWORD GetTextureUsage(GLenum internalformat, bool renderTarget);
D3DPOOL getPool() const;
DWORD getUsage() const;
virtual angle::Result getSurfaceLevel(const gl::Context *context,
gl::TextureTarget target,
int level,
bool dirty,
IDirect3DSurface9 **outSurface) = 0;
virtual angle::Result getBaseTexture(const gl::Context *context,
IDirect3DBaseTexture9 **outTexture) = 0;
int getTopLevel() const override;
bool isRenderTarget() const override;
bool isManaged() const override;
bool supportsNativeMipmapFunction() const override;
int getLevelCount() const override;
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) override;
protected:
int mTopLevel;
size_t mMipLevels;
size_t mTextureWidth;
size_t mTextureHeight;
GLenum mInternalFormat;
D3DFORMAT mTextureFormat;
Renderer9 *mRenderer;
TextureStorage9(Renderer9 *renderer, DWORD usage);
private:
const DWORD mD3DUsage;
const D3DPOOL mD3DPool;
};
class TextureStorage9_2D : public TextureStorage9
{
public:
TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain);
TextureStorage9_2D(Renderer9 *renderer,
GLenum internalformat,
bool renderTarget,
GLsizei width,
GLsizei height,
int levels);
~TextureStorage9_2D() override;
angle::Result getSurfaceLevel(const gl::Context *context,
gl::TextureTarget target,
int level,
bool dirty,
IDirect3DSurface9 **outSurface) override;
angle::Result findRenderTarget(const gl::Context *context,
const gl::ImageIndex &index,
GLsizei samples,
RenderTargetD3D **outRT) const override;
angle::Result getRenderTarget(const gl::Context *context,
const gl::ImageIndex &index,
GLsizei samples,
RenderTargetD3D **outRT) override;
angle::Result getBaseTexture(const gl::Context *context,
IDirect3DBaseTexture9 **outTexture) override;
angle::Result generateMipmap(const gl::Context *context,
const gl::ImageIndex &sourceIndex,
const gl::ImageIndex &destIndex) override;
angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
private:
IDirect3DTexture9 *mTexture;
std::vector<RenderTarget9 *> mRenderTargets;
};
class TextureStorage9_EGLImage final : public TextureStorage9
{
public:
TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image, RenderTarget9 *renderTarget9);
~TextureStorage9_EGLImage() override;
angle::Result getSurfaceLevel(const gl::Context *context,
gl::TextureTarget target,
int level,
bool dirty,
IDirect3DSurface9 **outSurface) override;
angle::Result findRenderTarget(const gl::Context *context,
const gl::ImageIndex &index,
GLsizei samples,
RenderTargetD3D **outRT) const override;
angle::Result getRenderTarget(const gl::Context *context,
const gl::ImageIndex &index,
GLsizei samples,
RenderTargetD3D **outRT) override;
angle::Result getBaseTexture(const gl::Context *context,
IDirect3DBaseTexture9 **outTexture) override;
angle::Result generateMipmap(const gl::Context *context,
const gl::ImageIndex &sourceIndex,
const gl::ImageIndex &destIndex) override;
angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
private:
EGLImageD3D *mImage;
};
class TextureStorage9_Cube : public TextureStorage9
{
public:
TextureStorage9_Cube(Renderer9 *renderer,
GLenum internalformat,
bool renderTarget,
int size,
int levels,
bool hintLevelZeroOnly);
~TextureStorage9_Cube() override;
angle::Result getSurfaceLevel(const gl::Context *context,
gl::TextureTarget target,
int level,
bool dirty,
IDirect3DSurface9 **outSurface) override;
angle::Result findRenderTarget(const gl::Context *context,
const gl::ImageIndex &index,
GLsizei samples,
RenderTargetD3D **outRT) const override;
angle::Result getRenderTarget(const gl::Context *context,
const gl::ImageIndex &index,
GLsizei samples,
RenderTargetD3D **outRT) override;
angle::Result getBaseTexture(const gl::Context *context,
IDirect3DBaseTexture9 **outTexture) override;
angle::Result generateMipmap(const gl::Context *context,
const gl::ImageIndex &sourceIndex,
const gl::ImageIndex &destIndex) override;
angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
private:
IDirect3DCubeTexture9 *mTexture;
RenderTarget9 *mRenderTarget[gl::kCubeFaceCount];
};
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_