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:
Jamie Madill 2016-12-20 10:11:45 -05:00 коммит произвёл Commit Bot
Родитель 842f23f8ca
Коммит 408293f8a4
22 изменённых файлов: 270 добавлений и 77 удалений

Просмотреть файл

@ -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();