зеркало из https://github.com/AvaloniaUI/angle.git
D3D11: Fix stale SRVs with tiny depth textures.
When the tiny depth texture would get re-created on change, it was not freeing any cached SRVs which were pointing to the old tex. Fix this by erasing the cache entry if the texure is recreated. Also include a test which hooks into the workarounds to force testing on every platform. Also narrow the workaround to only apply to depth/stencil textures which use these mips in GL, rather than D3D, where we always create a full mip chain. BUG=angleproject:1664 Change-Id: If0ac396b8847e1bf9b50165e5332da573e9bb3e4 Reviewed-on: https://chromium-review.googlesource.com/421567 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Родитель
842f23f8ca
Коммит
408293f8a4
|
@ -33,6 +33,8 @@
|
|||
namespace angle
|
||||
{
|
||||
|
||||
struct WorkaroundsD3D;
|
||||
|
||||
class Platform
|
||||
{
|
||||
public:
|
||||
|
@ -145,6 +147,9 @@ class Platform
|
|||
// Boolean histograms track two-state variables.
|
||||
virtual void histogramBoolean(const char *name, bool sample) { }
|
||||
|
||||
// Allows us to programatically override ANGLE's default workarounds for testing purposes.
|
||||
virtual void overrideWorkaroundsD3D(WorkaroundsD3D *workaroundsD3D) {}
|
||||
|
||||
protected:
|
||||
virtual ~Platform() { }
|
||||
};
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
|
||||
// WorkaroundsD3D.h: Workarounds for D3D driver bugs and other issues.
|
||||
|
||||
#ifndef LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_
|
||||
#define LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_
|
||||
#ifndef ANGLE_PLATFORM_WORKAROUNDSD3D_H_
|
||||
#define ANGLE_PLATFORM_WORKAROUNDSD3D_H_
|
||||
|
||||
// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate
|
||||
// independent of ANGLE's renderer. Workarounds should also be accessible
|
||||
// outside of the Renderer.
|
||||
|
||||
namespace rx
|
||||
namespace angle
|
||||
{
|
||||
struct D3DCompilerWorkarounds
|
||||
struct CompilerWorkaroundsD3D
|
||||
{
|
||||
bool skipOptimization = false;
|
||||
bool useMaxOptimization = false;
|
||||
|
@ -107,6 +107,6 @@ struct WorkaroundsD3D
|
|||
bool useSystemMemoryForConstantBuffers = false;
|
||||
};
|
||||
|
||||
} // namespace rx
|
||||
} // namespace angle
|
||||
|
||||
#endif // LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_
|
||||
#endif // ANGLE_PLATFORM_WORKAROUNDSD3D_H_
|
|
@ -30,7 +30,6 @@ namespace rx
|
|||
{
|
||||
class RendererD3D;
|
||||
class RenderTargetD3D;
|
||||
struct WorkaroundsD3D;
|
||||
|
||||
struct ClearParameters
|
||||
{
|
||||
|
|
|
@ -890,10 +890,10 @@ LinkResult ProgramD3D::load(const ContextImpl *contextImpl,
|
|||
|
||||
stream->readString(&mVertexHLSL);
|
||||
stream->readBytes(reinterpret_cast<unsigned char *>(&mVertexWorkarounds),
|
||||
sizeof(D3DCompilerWorkarounds));
|
||||
sizeof(angle::CompilerWorkaroundsD3D));
|
||||
stream->readString(&mPixelHLSL);
|
||||
stream->readBytes(reinterpret_cast<unsigned char *>(&mPixelWorkarounds),
|
||||
sizeof(D3DCompilerWorkarounds));
|
||||
sizeof(angle::CompilerWorkaroundsD3D));
|
||||
stream->readBool(&mUsesFragDepth);
|
||||
stream->readBool(&mUsesPointSize);
|
||||
stream->readBool(&mUsesFlatInterpolation);
|
||||
|
@ -1075,10 +1075,10 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
|
|||
|
||||
stream->writeString(mVertexHLSL);
|
||||
stream->writeBytes(reinterpret_cast<unsigned char *>(&mVertexWorkarounds),
|
||||
sizeof(D3DCompilerWorkarounds));
|
||||
sizeof(angle::CompilerWorkaroundsD3D));
|
||||
stream->writeString(mPixelHLSL);
|
||||
stream->writeBytes(reinterpret_cast<unsigned char *>(&mPixelWorkarounds),
|
||||
sizeof(D3DCompilerWorkarounds));
|
||||
sizeof(angle::CompilerWorkaroundsD3D));
|
||||
stream->writeInt(mUsesFragDepth);
|
||||
stream->writeInt(mUsesPointSize);
|
||||
stream->writeInt(mUsesFlatInterpolation);
|
||||
|
@ -1309,8 +1309,8 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::ContextSta
|
|||
|
||||
gl::Error error = mRenderer->compileToExecutable(
|
||||
*currentInfoLog, geometryHLSL, SHADER_GEOMETRY, mStreamOutVaryings,
|
||||
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), D3DCompilerWorkarounds(),
|
||||
&mGeometryExecutables[geometryShaderType]);
|
||||
(mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
|
||||
angle::CompilerWorkaroundsD3D(), &mGeometryExecutables[geometryShaderType]);
|
||||
|
||||
if (!infoLog && error.isError())
|
||||
{
|
||||
|
@ -2249,10 +2249,10 @@ void ProgramD3D::reset()
|
|||
}
|
||||
|
||||
mVertexHLSL.clear();
|
||||
mVertexWorkarounds = D3DCompilerWorkarounds();
|
||||
mVertexWorkarounds = angle::CompilerWorkaroundsD3D();
|
||||
|
||||
mPixelHLSL.clear();
|
||||
mPixelWorkarounds = D3DCompilerWorkarounds();
|
||||
mPixelWorkarounds = angle::CompilerWorkaroundsD3D();
|
||||
mUsesFragDepth = false;
|
||||
mPixelShaderKey.clear();
|
||||
mUsesPointSize = false;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "libANGLE/formatutils.h"
|
||||
#include "libANGLE/renderer/ProgramImpl.h"
|
||||
#include "libANGLE/renderer/d3d/DynamicHLSL.h"
|
||||
#include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
|
||||
#include "platform/WorkaroundsD3D.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
@ -374,10 +374,10 @@ class ProgramD3D : public ProgramImpl
|
|||
std::vector<ShaderExecutableD3D *> mGeometryExecutables;
|
||||
|
||||
std::string mVertexHLSL;
|
||||
D3DCompilerWorkarounds mVertexWorkarounds;
|
||||
angle::CompilerWorkaroundsD3D mVertexWorkarounds;
|
||||
|
||||
std::string mPixelHLSL;
|
||||
D3DCompilerWorkarounds mPixelWorkarounds;
|
||||
angle::CompilerWorkaroundsD3D mPixelWorkarounds;
|
||||
bool mUsesFragDepth;
|
||||
std::vector<PixelShaderOutputVariable> mPixelShaderKey;
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
#include "libANGLE/Device.h"
|
||||
#include "libANGLE/formatutils.h"
|
||||
#include "libANGLE/renderer/d3d/VertexDataManager.h"
|
||||
#include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
|
||||
#include "libANGLE/renderer/d3d/hlsl/hlsl_utils.h"
|
||||
#include "libANGLE/renderer/d3d/formatutilsD3D.h"
|
||||
#include "libANGLE/Version.h"
|
||||
#include "libANGLE/WorkerThread.h"
|
||||
#include "platform/WorkaroundsD3D.h"
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
@ -148,7 +148,7 @@ class RendererD3D : public BufferFactoryD3D
|
|||
|
||||
virtual int getMajorShaderModel() const = 0;
|
||||
|
||||
const WorkaroundsD3D &getWorkarounds() const;
|
||||
const angle::WorkaroundsD3D &getWorkarounds() const;
|
||||
|
||||
// Pixel operations
|
||||
virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
|
||||
|
@ -191,7 +191,7 @@ class RendererD3D : public BufferFactoryD3D
|
|||
ShaderType type,
|
||||
const std::vector<D3DVarying> &streamOutVaryings,
|
||||
bool separatedOutputBuffers,
|
||||
const D3DCompilerWorkarounds &workarounds,
|
||||
const angle::CompilerWorkaroundsD3D &workarounds,
|
||||
ShaderExecutableD3D **outExectuable) = 0;
|
||||
virtual gl::Error ensureHLSLCompilerInitialized() = 0;
|
||||
|
||||
|
@ -292,7 +292,7 @@ class RendererD3D : public BufferFactoryD3D
|
|||
FramebufferTextureArray *outTextureArray);
|
||||
gl::Texture *getIncompleteTexture(GLImplFactory *implFactory, GLenum type);
|
||||
|
||||
virtual WorkaroundsD3D generateWorkarounds() const = 0;
|
||||
virtual angle::WorkaroundsD3D generateWorkarounds() const = 0;
|
||||
|
||||
mutable bool mCapsInitialized;
|
||||
mutable gl::Caps mNativeCaps;
|
||||
|
@ -303,7 +303,7 @@ class RendererD3D : public BufferFactoryD3D
|
|||
gl::TextureMap mIncompleteTextures;
|
||||
|
||||
mutable bool mWorkaroundsInitialized;
|
||||
mutable WorkaroundsD3D mWorkarounds;
|
||||
mutable angle::WorkaroundsD3D mWorkarounds;
|
||||
|
||||
bool mDisjoint;
|
||||
bool mDeviceLost;
|
||||
|
|
|
@ -40,7 +40,7 @@ const char *GetShaderTypeString(GLenum type)
|
|||
namespace rx
|
||||
{
|
||||
|
||||
ShaderD3D::ShaderD3D(const gl::ShaderState &data, const WorkaroundsD3D &workarounds)
|
||||
ShaderD3D::ShaderD3D(const gl::ShaderState &data, const angle::WorkaroundsD3D &workarounds)
|
||||
: ShaderImpl(data), mAdditionalOptions(0)
|
||||
{
|
||||
uncompile();
|
||||
|
@ -101,7 +101,7 @@ void ShaderD3D::uncompile()
|
|||
mDebugInfo.clear();
|
||||
}
|
||||
|
||||
void ShaderD3D::generateWorkarounds(D3DCompilerWorkarounds *workarounds) const
|
||||
void ShaderD3D::generateWorkarounds(angle::CompilerWorkaroundsD3D *workarounds) const
|
||||
{
|
||||
if (mUsesDiscardRewriting)
|
||||
{
|
||||
|
|
|
@ -13,18 +13,22 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
struct CompilerWorkaroundsD3D;
|
||||
struct WorkaroundsD3D;
|
||||
}
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class DynamicHLSL;
|
||||
class RendererD3D;
|
||||
struct D3DCompilerWorkarounds;
|
||||
struct D3DUniform;
|
||||
struct WorkaroundsD3D;
|
||||
|
||||
class ShaderD3D : public ShaderImpl
|
||||
{
|
||||
public:
|
||||
ShaderD3D(const gl::ShaderState &data, const WorkaroundsD3D &workarounds);
|
||||
ShaderD3D(const gl::ShaderState &data, const angle::WorkaroundsD3D &workarounds);
|
||||
virtual ~ShaderD3D();
|
||||
|
||||
// ShaderImpl implementation
|
||||
|
@ -45,7 +49,7 @@ class ShaderD3D : public ShaderImpl
|
|||
unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
|
||||
void appendDebugInfo(const std::string &info) const { mDebugInfo += info; }
|
||||
|
||||
void generateWorkarounds(D3DCompilerWorkarounds *workarounds) const;
|
||||
void generateWorkarounds(angle::CompilerWorkaroundsD3D *workarounds) const;
|
||||
|
||||
bool usesMultipleRenderTargets() const { return mUsesMultipleRenderTargets; }
|
||||
bool usesFragColor() const { return mUsesFragColor; }
|
||||
|
|
|
@ -2978,7 +2978,7 @@ std::string Renderer11::getShaderModelSuffix() const
|
|||
}
|
||||
}
|
||||
|
||||
const WorkaroundsD3D &RendererD3D::getWorkarounds() const
|
||||
const angle::WorkaroundsD3D &RendererD3D::getWorkarounds() const
|
||||
{
|
||||
if (!mWorkaroundsInitialized)
|
||||
{
|
||||
|
@ -3548,7 +3548,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog,
|
|||
ShaderType type,
|
||||
const std::vector<D3DVarying> &streamOutVaryings,
|
||||
bool separatedOutputBuffers,
|
||||
const D3DCompilerWorkarounds &workarounds,
|
||||
const angle::CompilerWorkaroundsD3D &workarounds,
|
||||
ShaderExecutableD3D **outExectuable)
|
||||
{
|
||||
std::stringstream profileStream;
|
||||
|
@ -4425,7 +4425,7 @@ void Renderer11::generateCaps(gl::Caps *outCaps,
|
|||
outExtensions, outLimitations);
|
||||
}
|
||||
|
||||
WorkaroundsD3D Renderer11::generateWorkarounds() const
|
||||
angle::WorkaroundsD3D Renderer11::generateWorkarounds() const
|
||||
{
|
||||
return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription);
|
||||
}
|
||||
|
|
|
@ -248,7 +248,7 @@ class Renderer11 : public RendererD3D
|
|||
ShaderType type,
|
||||
const std::vector<D3DVarying> &streamOutVaryings,
|
||||
bool separatedOutputBuffers,
|
||||
const D3DCompilerWorkarounds &workarounds,
|
||||
const angle::CompilerWorkaroundsD3D &workarounds,
|
||||
ShaderExecutableD3D **outExectuable) override;
|
||||
gl::Error ensureHLSLCompilerInitialized() override;
|
||||
|
||||
|
@ -398,7 +398,7 @@ class Renderer11 : public RendererD3D
|
|||
gl::Extensions *outExtensions,
|
||||
gl::Limitations *outLimitations) const override;
|
||||
|
||||
WorkaroundsD3D generateWorkarounds() const override;
|
||||
angle::WorkaroundsD3D generateWorkarounds() const override;
|
||||
|
||||
gl::Error drawLineLoop(const gl::ContextState &data,
|
||||
GLsizei count,
|
||||
|
|
|
@ -217,16 +217,28 @@ gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState,
|
|||
// 2. this is a stencil texture.
|
||||
bool hasStencil = (mFormatInfo.format().stencilBits > 0);
|
||||
// 3. the texture has a 1x1 or 2x2 mip.
|
||||
bool hasSmallMips = (getLevelWidth(mMipLevels - 1) <= 2 || getLevelHeight(mMipLevels - 1) <= 2);
|
||||
int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1;
|
||||
bool hasSmallMips =
|
||||
(getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2);
|
||||
|
||||
bool useDropStencil = (workaround && hasStencil && hasSmallMips);
|
||||
SRVKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil);
|
||||
if (useDropStencil)
|
||||
{
|
||||
// Ensure drop texture gets re-created, if SRV is cached.
|
||||
ANGLE_TRY(createDropStencilTexture());
|
||||
// Ensure drop texture gets created.
|
||||
DropStencil result = DropStencil::CREATED;
|
||||
ANGLE_TRY_RESULT(ensureDropStencilTexture(), result);
|
||||
|
||||
// Clear the SRV cache if necessary.
|
||||
// TODO(jmadill): Re-use find query result.
|
||||
auto srvEntry = mSrvCache.find(key);
|
||||
if (result == DropStencil::CREATED && srvEntry != mSrvCache.end())
|
||||
{
|
||||
SafeRelease(srvEntry->second);
|
||||
mSrvCache.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
SRVKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil);
|
||||
ANGLE_TRY(getCachedOrCreateSRV(key, outSRV));
|
||||
|
||||
return gl::NoError();
|
||||
|
@ -687,10 +699,10 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index,
|
|||
return gl::NoError();
|
||||
}
|
||||
|
||||
gl::Error TextureStorage11::createDropStencilTexture()
|
||||
gl::ErrorOrResult<TextureStorage11::DropStencil> TextureStorage11::ensureDropStencilTexture()
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return gl::Error(GL_INVALID_OPERATION, "Drop stencil texture not implemented.");
|
||||
return gl::InternalError() << "Drop stencil texture not implemented.";
|
||||
}
|
||||
|
||||
TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain)
|
||||
|
@ -1309,11 +1321,11 @@ gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11Render
|
|||
return gl::NoError();
|
||||
}
|
||||
|
||||
gl::Error TextureStorage11_2D::createDropStencilTexture()
|
||||
gl::ErrorOrResult<TextureStorage11::DropStencil> TextureStorage11_2D::ensureDropStencilTexture()
|
||||
{
|
||||
if (mDropStencilTexture)
|
||||
{
|
||||
return gl::NoError();
|
||||
return DropStencil::ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC dropDesc = {};
|
||||
|
@ -1334,13 +1346,13 @@ gl::Error TextureStorage11_2D::createDropStencilTexture()
|
|||
HRESULT hr = device->CreateTexture2D(&dropDesc, nullptr, &mDropStencilTexture);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return gl::Error(GL_INVALID_OPERATION, "Error creating drop stencil texture.");
|
||||
return gl::InternalError() << "Error creating drop stencil texture.";
|
||||
}
|
||||
d3d11::SetDebugName(mDropStencilTexture, "TexStorage2D.DropStencil");
|
||||
|
||||
ANGLE_TRY(initDropStencilTexture(gl::ImageIndexIterator::Make2D(0, mMipLevels)));
|
||||
|
||||
return gl::NoError();
|
||||
return DropStencil::CREATED;
|
||||
}
|
||||
|
||||
TextureStorage11_External::TextureStorage11_External(
|
||||
|
@ -2473,11 +2485,11 @@ gl::Error TextureStorage11::initDropStencilTexture(const gl::ImageIndexIterator
|
|||
return gl::NoError();
|
||||
}
|
||||
|
||||
gl::Error TextureStorage11_Cube::createDropStencilTexture()
|
||||
gl::ErrorOrResult<TextureStorage11::DropStencil> TextureStorage11_Cube::ensureDropStencilTexture()
|
||||
{
|
||||
if (mDropStencilTexture)
|
||||
{
|
||||
return gl::NoError();
|
||||
return DropStencil::ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC dropDesc = {};
|
||||
|
@ -2498,13 +2510,13 @@ gl::Error TextureStorage11_Cube::createDropStencilTexture()
|
|||
HRESULT hr = device->CreateTexture2D(&dropDesc, nullptr, &mDropStencilTexture);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return gl::Error(GL_INVALID_OPERATION, "Error creating drop stencil texture.");
|
||||
return gl::InternalError() << "Error creating drop stencil texture.";
|
||||
}
|
||||
d3d11::SetDebugName(mDropStencilTexture, "TexStorageCube.DropStencil");
|
||||
|
||||
ANGLE_TRY(initDropStencilTexture(gl::ImageIndexIterator::MakeCube(0, mMipLevels)));
|
||||
|
||||
return gl::NoError();
|
||||
return DropStencil::CREATED;
|
||||
}
|
||||
|
||||
TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer,
|
||||
|
@ -3350,11 +3362,12 @@ gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel,
|
|||
return gl::NoError();
|
||||
}
|
||||
|
||||
gl::Error TextureStorage11_2DArray::createDropStencilTexture()
|
||||
gl::ErrorOrResult<TextureStorage11::DropStencil>
|
||||
TextureStorage11_2DArray::ensureDropStencilTexture()
|
||||
{
|
||||
if (mDropStencilTexture)
|
||||
{
|
||||
return gl::NoError();
|
||||
return DropStencil::ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC dropDesc = {};
|
||||
|
@ -3375,7 +3388,7 @@ gl::Error TextureStorage11_2DArray::createDropStencilTexture()
|
|||
HRESULT hr = device->CreateTexture2D(&dropDesc, nullptr, &mDropStencilTexture);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return gl::Error(GL_INVALID_OPERATION, "Error creating drop stencil texture.");
|
||||
return gl::InternalError() << "Error creating drop stencil texture.";
|
||||
}
|
||||
d3d11::SetDebugName(mDropStencilTexture, "TexStorage2DArray.DropStencil");
|
||||
|
||||
|
@ -3384,7 +3397,7 @@ gl::Error TextureStorage11_2DArray::createDropStencilTexture()
|
|||
ANGLE_TRY(initDropStencilTexture(
|
||||
gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data())));
|
||||
|
||||
return gl::NoError();
|
||||
return DropStencil::CREATED;
|
||||
}
|
||||
|
||||
} // namespace rx
|
||||
|
|
|
@ -95,7 +95,12 @@ class TextureStorage11 : public TextureStorage
|
|||
gl::Error getSRVLevel(int mipLevel, bool blitSRV, ID3D11ShaderResourceView **outSRV);
|
||||
|
||||
// Get a version of a depth texture with only depth information, not stencil.
|
||||
virtual gl::Error createDropStencilTexture();
|
||||
enum DropStencil
|
||||
{
|
||||
CREATED,
|
||||
ALREADY_EXISTS
|
||||
};
|
||||
virtual gl::ErrorOrResult<DropStencil> ensureDropStencilTexture();
|
||||
gl::Error initDropStencilTexture(const gl::ImageIndexIterator &it);
|
||||
|
||||
// The baseLevel parameter should *not* have mTopLevel applied.
|
||||
|
@ -167,7 +172,7 @@ class TextureStorage11_2D : public TextureStorage11
|
|||
gl::Error getSwizzleTexture(ID3D11Resource **outTexture) override;
|
||||
gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) override;
|
||||
|
||||
gl::Error createDropStencilTexture() override;
|
||||
gl::ErrorOrResult<DropStencil> ensureDropStencilTexture() override;
|
||||
|
||||
gl::Error ensureTextureExists(int mipLevels);
|
||||
|
||||
|
@ -312,7 +317,7 @@ class TextureStorage11_Cube : public TextureStorage11
|
|||
virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
|
||||
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
|
||||
|
||||
gl::Error createDropStencilTexture() override;
|
||||
gl::ErrorOrResult<DropStencil> ensureDropStencilTexture() override;
|
||||
|
||||
gl::Error ensureTextureExists(int mipLevels);
|
||||
|
||||
|
@ -397,7 +402,7 @@ class TextureStorage11_2DArray : public TextureStorage11
|
|||
virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
|
||||
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
|
||||
|
||||
gl::Error createDropStencilTexture() override;
|
||||
gl::ErrorOrResult<DropStencil> ensureDropStencilTexture() override;
|
||||
|
||||
private:
|
||||
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
|
||||
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
|
||||
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
|
||||
#include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
|
||||
#include "libANGLE/renderer/driver_utils.h"
|
||||
#include "platform/Platform.h"
|
||||
#include "platform/WorkaroundsD3D.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
@ -1818,12 +1819,12 @@ ID3D11BlendState *LazyBlendState::resolve(ID3D11Device *device)
|
|||
return mResource;
|
||||
}
|
||||
|
||||
WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
||||
const DXGI_ADAPTER_DESC &adapterDesc)
|
||||
angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
||||
const DXGI_ADAPTER_DESC &adapterDesc)
|
||||
{
|
||||
bool is9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
|
||||
|
||||
WorkaroundsD3D workarounds;
|
||||
angle::WorkaroundsD3D workarounds;
|
||||
workarounds.mrtPerfWorkaround = true;
|
||||
workarounds.setDataFasterThanImageUpload = true;
|
||||
workarounds.zeroMaxLodWorkaround = is9_3;
|
||||
|
@ -1876,6 +1877,9 @@ WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
|||
|
||||
workarounds.useSystemMemoryForConstantBuffers = IsIntel(adapterDesc.VendorId);
|
||||
|
||||
// Call platform hooks for testing overrides.
|
||||
ANGLEPlatformCurrent()->overrideWorkaroundsD3D(&workarounds);
|
||||
|
||||
return workarounds;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ namespace rx
|
|||
{
|
||||
class Renderer11;
|
||||
class RenderTarget11;
|
||||
struct WorkaroundsD3D;
|
||||
struct Renderer11DeviceCaps;
|
||||
|
||||
using RenderTargetArray = std::array<RenderTarget11 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
|
||||
|
@ -353,8 +352,8 @@ void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, c
|
|||
}
|
||||
}
|
||||
|
||||
WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
||||
const DXGI_ADAPTER_DESC &adapterDesc);
|
||||
angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
||||
const DXGI_ADAPTER_DESC &adapterDesc);
|
||||
|
||||
enum ReservedConstantBufferSlot
|
||||
{
|
||||
|
|
|
@ -2623,7 +2623,7 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog,
|
|||
ShaderType type,
|
||||
const std::vector<D3DVarying> &streamOutVaryings,
|
||||
bool separatedOutputBuffers,
|
||||
const D3DCompilerWorkarounds &workarounds,
|
||||
const angle::CompilerWorkaroundsD3D &workarounds,
|
||||
ShaderExecutableD3D **outExectuable)
|
||||
{
|
||||
// Transform feedback is not supported in ES2 or D3D9
|
||||
|
@ -2908,7 +2908,7 @@ void Renderer9::generateCaps(gl::Caps *outCaps,
|
|||
outExtensions, outLimitations);
|
||||
}
|
||||
|
||||
WorkaroundsD3D Renderer9::generateWorkarounds() const
|
||||
angle::WorkaroundsD3D Renderer9::generateWorkarounds() const
|
||||
{
|
||||
return d3d9::GenerateWorkarounds();
|
||||
}
|
||||
|
|
|
@ -245,7 +245,7 @@ class Renderer9 : public RendererD3D
|
|||
ShaderType type,
|
||||
const std::vector<D3DVarying> &streamOutVaryings,
|
||||
bool separatedOutputBuffers,
|
||||
const D3DCompilerWorkarounds &workarounds,
|
||||
const angle::CompilerWorkaroundsD3D &workarounds,
|
||||
ShaderExecutableD3D **outExectuable) override;
|
||||
gl::Error ensureHLSLCompilerInitialized() override;
|
||||
|
||||
|
@ -370,7 +370,7 @@ class Renderer9 : public RendererD3D
|
|||
gl::Extensions *outExtensions,
|
||||
gl::Limitations *outLimitations) const override;
|
||||
|
||||
WorkaroundsD3D generateWorkarounds() const override;
|
||||
angle::WorkaroundsD3D generateWorkarounds() const override;
|
||||
|
||||
gl::Error setBlendDepthRasterStates(const gl::ContextState &glData, GLenum drawMode);
|
||||
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
|
||||
#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
|
||||
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
|
||||
#include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
|
||||
#include "libANGLE/renderer/driver_utils.h"
|
||||
#include "platform/Platform.h"
|
||||
#include "platform/WorkaroundsD3D.h"
|
||||
|
||||
#include "third_party/systeminfo/SystemInfo.h"
|
||||
|
||||
|
@ -642,9 +643,9 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize
|
|||
*levelOffset = upsampleCount;
|
||||
}
|
||||
|
||||
WorkaroundsD3D GenerateWorkarounds()
|
||||
angle::WorkaroundsD3D GenerateWorkarounds()
|
||||
{
|
||||
WorkaroundsD3D workarounds;
|
||||
angle::WorkaroundsD3D workarounds;
|
||||
workarounds.mrtPerfWorkaround = true;
|
||||
workarounds.setDataFasterThanImageUpload = false;
|
||||
workarounds.useInstancedPointSpriteEmulation = false;
|
||||
|
@ -652,6 +653,9 @@ WorkaroundsD3D GenerateWorkarounds()
|
|||
// TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
|
||||
workarounds.expandIntegerPowExpressions = true;
|
||||
|
||||
// Call platform hooks for testing overrides.
|
||||
ANGLEPlatformCurrent()->overrideWorkaroundsD3D(&workarounds);
|
||||
|
||||
return workarounds;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "common/Color.h"
|
||||
#include "libANGLE/Caps.h"
|
||||
#include "libANGLE/Error.h"
|
||||
#include "platform/WorkaroundsD3D.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
@ -22,7 +23,6 @@ class FramebufferAttachment;
|
|||
namespace rx
|
||||
{
|
||||
class RenderTarget9;
|
||||
struct WorkaroundsD3D;
|
||||
|
||||
namespace gl_d3d9
|
||||
{
|
||||
|
@ -87,9 +87,9 @@ inline bool isDeviceLostError(HRESULT errorCode)
|
|||
}
|
||||
}
|
||||
|
||||
WorkaroundsD3D GenerateWorkarounds();
|
||||
angle::WorkaroundsD3D GenerateWorkarounds();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace d3d9
|
||||
|
||||
#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
'../include/GLSLANG/ShaderVars.h',
|
||||
'../include/KHR/khrplatform.h',
|
||||
'../include/platform/Platform.h',
|
||||
'../include/platform/WorkaroundsD3D.h',
|
||||
],
|
||||
'libangle_sources':
|
||||
[
|
||||
|
@ -269,7 +270,6 @@
|
|||
'libANGLE/renderer/d3d/VertexBuffer.h',
|
||||
'libANGLE/renderer/d3d/VertexDataManager.cpp',
|
||||
'libANGLE/renderer/d3d/VertexDataManager.h',
|
||||
'libANGLE/renderer/d3d/WorkaroundsD3D.h',
|
||||
],
|
||||
'libangle_d3d_hlsl_sources':
|
||||
[
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
//
|
||||
|
||||
#include "test_utils/ANGLETest.h"
|
||||
#include "test_utils/gl_raii.h"
|
||||
|
||||
#include "common/mathutil.h"
|
||||
#include "platform/WorkaroundsD3D.h"
|
||||
|
||||
using namespace angle;
|
||||
|
||||
|
@ -190,3 +194,139 @@ ANGLE_INSTANTIATE_TEST(DepthStencilFormatsTest,
|
|||
ES2_OPENGL(),
|
||||
ES2_OPENGLES());
|
||||
ANGLE_INSTANTIATE_TEST(DepthStencilFormatsTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
|
||||
|
||||
class TinyDepthStencilWorkaroundTest : public ANGLETest
|
||||
{
|
||||
public:
|
||||
TinyDepthStencilWorkaroundTest()
|
||||
{
|
||||
setWindowWidth(512);
|
||||
setWindowHeight(512);
|
||||
setConfigRedBits(8);
|
||||
setConfigGreenBits(8);
|
||||
setConfigBlueBits(8);
|
||||
setConfigAlphaBits(8);
|
||||
}
|
||||
|
||||
// Override the workarounds to enable "tiny" depth/stencil textures.
|
||||
void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
|
||||
{
|
||||
workarounds->emulateTinyStencilTextures = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Tests that the tiny depth stencil textures workaround does not "stick" depth textures.
|
||||
// http://anglebug.com/1664
|
||||
TEST_P(TinyDepthStencilWorkaroundTest, DepthTexturesStick)
|
||||
{
|
||||
const std::string &drawVS =
|
||||
"#version 100\n"
|
||||
"attribute vec3 vertex;\n"
|
||||
"void main () {\n"
|
||||
" gl_Position = vec4(vertex.x, vertex.y, vertex.z * 2.0 - 1.0, 1);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string &drawFS =
|
||||
"#version 100\n"
|
||||
"void main () {\n"
|
||||
" gl_FragColor = vec4 (1.);\n"
|
||||
"}\n";
|
||||
|
||||
ANGLE_GL_PROGRAM(drawProgram, drawVS, drawFS);
|
||||
|
||||
const std::string &blitVS =
|
||||
"#version 100\n"
|
||||
"attribute vec2 vertex;\n"
|
||||
"varying vec2 position;\n"
|
||||
"void main () {\n"
|
||||
" position = vertex * .5 + .5;\n"
|
||||
" gl_Position = vec4(vertex, 0, 1);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string &blitFS =
|
||||
"#version 100\n"
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2D texture;\n"
|
||||
"varying vec2 position;\n"
|
||||
"void main () {\n"
|
||||
" gl_FragColor = vec4 (texture2D (texture, position).rrr, 1.);\n"
|
||||
"}\n";
|
||||
|
||||
ANGLE_GL_PROGRAM(blitProgram, blitVS, blitFS);
|
||||
|
||||
GLint blitTextureLocation = glGetUniformLocation(blitProgram.get(), "texture");
|
||||
ASSERT_NE(-1, blitTextureLocation);
|
||||
|
||||
GLTexture colorTex;
|
||||
glBindTexture(GL_TEXTURE_2D, colorTex.get());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
GLTexture depthTex;
|
||||
glBindTexture(GL_TEXTURE_2D, depthTex.get());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
ASSERT_EQ(getWindowWidth(), getWindowHeight());
|
||||
int levels = gl::log2(getWindowWidth());
|
||||
for (int mipLevel = 0; mipLevel <= levels; ++mipLevel)
|
||||
{
|
||||
int size = getWindowWidth() >> mipLevel;
|
||||
glTexImage2D(GL_TEXTURE_2D, mipLevel, GL_DEPTH_STENCIL, size, size, 0, GL_DEPTH_STENCIL,
|
||||
GL_UNSIGNED_INT_24_8_OES, nullptr);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLFramebuffer framebuffer;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex.get(), 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex.get(), 0);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glDepthRangef(0.0f, 1.0f);
|
||||
glViewport(0, 0, getWindowWidth(), getWindowHeight());
|
||||
glClearColor(0, 0, 0, 1);
|
||||
|
||||
// Draw loop.
|
||||
for (unsigned int frame = 0; frame < 3; ++frame)
|
||||
{
|
||||
// draw into FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
float depth = ((frame % 2 == 0) ? 0.0f : 1.0f);
|
||||
drawQuad(drawProgram.get(), "vertex", depth);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// blit FBO
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glUseProgram(blitProgram.get());
|
||||
glUniform1i(blitTextureLocation, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, depthTex.get());
|
||||
|
||||
drawQuad(blitProgram.get(), "vertex", 0.5f);
|
||||
|
||||
Vector4 depthVec(depth, depth, depth, 1);
|
||||
GLColor depthColor(depthVec);
|
||||
|
||||
EXPECT_PIXEL_COLOR_NEAR(0, 0, depthColor, 1);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
}
|
||||
|
||||
ANGLE_INSTANTIATE_TEST(TinyDepthStencilWorkaroundTest, ES3_D3D11());
|
||||
|
|
|
@ -46,17 +46,18 @@ GLubyte ColorDenorm(float colorValue)
|
|||
class TestPlatform : public angle::Platform
|
||||
{
|
||||
public:
|
||||
TestPlatform() : mIgnoreMessages(false) {}
|
||||
|
||||
void logError(const char *errorMessage) override;
|
||||
void logWarning(const char *warningMessage) override;
|
||||
void logInfo(const char *infoMessage) override;
|
||||
void overrideWorkaroundsD3D(WorkaroundsD3D *workaroundsD3D) override;
|
||||
|
||||
void ignoreMessages();
|
||||
void enableMessages();
|
||||
void setCurrentTest(ANGLETest *currentTest);
|
||||
|
||||
private:
|
||||
bool mIgnoreMessages;
|
||||
bool mIgnoreMessages = false;
|
||||
ANGLETest *mCurrentTest = nullptr;
|
||||
};
|
||||
|
||||
void TestPlatform::logError(const char *errorMessage)
|
||||
|
@ -83,6 +84,14 @@ void TestPlatform::logInfo(const char *infoMessage)
|
|||
angle::WriteDebugMessage("%s\n", infoMessage);
|
||||
}
|
||||
|
||||
void TestPlatform::overrideWorkaroundsD3D(WorkaroundsD3D *workaroundsD3D)
|
||||
{
|
||||
if (mCurrentTest)
|
||||
{
|
||||
mCurrentTest->overrideWorkaroundsD3D(workaroundsD3D);
|
||||
}
|
||||
}
|
||||
|
||||
void TestPlatform::ignoreMessages()
|
||||
{
|
||||
mIgnoreMessages = true;
|
||||
|
@ -93,6 +102,11 @@ void TestPlatform::enableMessages()
|
|||
mIgnoreMessages = false;
|
||||
}
|
||||
|
||||
void TestPlatform::setCurrentTest(ANGLETest *currentTest)
|
||||
{
|
||||
mCurrentTest = currentTest;
|
||||
}
|
||||
|
||||
TestPlatform g_testPlatformInstance;
|
||||
|
||||
std::array<angle::Vector3, 4> GetIndexedQuadVertices()
|
||||
|
@ -205,6 +219,7 @@ ANGLETest::~ANGLETest()
|
|||
void ANGLETest::SetUp()
|
||||
{
|
||||
angle::g_testPlatformInstance.enableMessages();
|
||||
angle::g_testPlatformInstance.setCurrentTest(this);
|
||||
|
||||
// Resize the window before creating the context so that the first make current
|
||||
// sets the viewport and scissor box to the right size.
|
||||
|
@ -242,6 +257,7 @@ void ANGLETest::SetUp()
|
|||
|
||||
void ANGLETest::TearDown()
|
||||
{
|
||||
angle::g_testPlatformInstance.setCurrentTest(nullptr);
|
||||
checkD3D11SDKLayersMessages();
|
||||
|
||||
const auto &info = testing::UnitTest::GetInstance()->current_test_info();
|
||||
|
|
|
@ -84,6 +84,8 @@ struct GLColor
|
|||
static const GLColor yellow;
|
||||
};
|
||||
|
||||
struct WorkaroundsD3D;
|
||||
|
||||
// Useful to cast any type to GLubyte.
|
||||
template <typename TR, typename TG, typename TB, typename TA>
|
||||
GLColor MakeGLColor(TR r, TG g, TB b, TA a)
|
||||
|
@ -145,6 +147,8 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
|
|||
static void SetWindowVisible(bool isVisible);
|
||||
static bool eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName);
|
||||
|
||||
virtual void overrideWorkaroundsD3D(angle::WorkaroundsD3D *workaroundsD3D) {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp();
|
||||
virtual void TearDown();
|
||||
|
|
Загрузка…
Ссылка в новой задаче