Commit 752ce192 by Gregoire Payen de La Garanderie Committed by Jamie Madill

D3D11: Use DX generateMips to generate mipmaps whenever possible.

BUG=angleproject:974 Change-Id: I95937fe7a0833de77c52f838ebb3ecba55dfbf8a Reviewed-on: https://chromium-review.googlesource.com/265640Tested-by: 's avatarGregoire Payen de La Garanderie <Gregory.Payen@imgtec.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 28eb65e3
......@@ -277,7 +277,7 @@ Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, c
Error Texture::generateMipmaps()
{
Error error = mTexture->generateMipmaps();
Error error = mTexture->generateMipmaps(getSamplerState());
if (error.isError())
{
return error;
......
......@@ -60,7 +60,7 @@ class TextureImpl : angle::NonCopyable
virtual gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) = 0;
virtual gl::Error generateMipmaps() = 0;
virtual gl::Error generateMipmaps(const gl::SamplerState &samplerState) = 0;
virtual void bindTexImage(egl::Surface *surface) = 0;
virtual void releaseTexImage() = 0;
......
......@@ -163,6 +163,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
// Image operations
virtual ImageD3D *createImage() = 0;
virtual gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) = 0;
virtual gl::Error generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState) = 0;
virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) = 0;
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) = 0;
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) = 0;
......
......@@ -376,7 +376,7 @@ ImageD3D *TextureD3D::getBaseLevelImage() const
return getImage(getImageIndex(0, 0));
}
gl::Error TextureD3D::generateMipmaps()
gl::Error TextureD3D::generateMipmaps(const gl::SamplerState &samplerState)
{
GLint mipCount = mipLevels();
......@@ -405,6 +405,38 @@ gl::Error TextureD3D::generateMipmaps()
// Set up proper mipmap chain in our Image array.
initMipmapsImages();
if (mTexStorage && mTexStorage->supportsNativeMipmapFunction())
{
gl::Error error = updateStorage();
if (error.isError())
{
return error;
}
// Generate the mipmap chain using the ad-hoc DirectX function.
error = mRenderer->generateMipmapsUsingD3D(mTexStorage, samplerState);
if (error.isError())
{
return error;
}
}
else
{
// Generate the mipmap chain, one level at a time.
gl::Error error = generateMipmapsUsingImages();
if (error.isError())
{
return error;
}
}
return gl::Error(GL_NO_ERROR);
}
gl::Error TextureD3D::generateMipmapsUsingImages()
{
GLint mipCount = mipLevels();
// We know that all layers have the same dimension, for the texture to be complete
GLint layerCount = static_cast<GLint>(getLayerCount(0));
......
......@@ -60,7 +60,7 @@ class TextureD3D : public TextureImpl
virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0;
virtual bool isValidIndex(const gl::ImageIndex &index) const = 0;
virtual gl::Error generateMipmaps();
virtual gl::Error generateMipmaps(const gl::SamplerState &samplerState);
TextureStorage *getStorage();
ImageD3D *getBaseLevelImage() const;
......@@ -106,6 +106,8 @@ class TextureD3D : public TextureImpl
virtual gl::Error updateStorage() = 0;
bool shouldUseSetData(const ImageD3D *image) const;
gl::Error generateMipmapsUsingImages();
};
class TextureD3D_2D : public TextureD3D
......
......@@ -39,6 +39,7 @@ class TextureStorage : angle::NonCopyable
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 gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0;
......
......@@ -3070,6 +3070,25 @@ gl::Error Renderer11::generateMipmap(ImageD3D *dest, ImageD3D *src)
return Image11::generateMipmap(dest11, src11);
}
gl::Error Renderer11::generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState)
{
TextureStorage11 *storage11 = GetAs<TextureStorage11>(storage);
ASSERT(storage11->isRenderTarget());
ASSERT(storage11->supportsNativeMipmapFunction());
ID3D11ShaderResourceView *srv;
gl::Error error = storage11->getSRVLevels(samplerState.baseLevel, samplerState.maxLevel, &srv);
if (error.isError())
{
return error;
}
mDeviceContext->GenerateMips(srv);
return gl::Error(GL_NO_ERROR);
}
TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain)
{
SwapChain11 *swapChain11 = GetAs<SwapChain11>(swapChain);
......
......@@ -185,6 +185,7 @@ class Renderer11 : public RendererD3D
// Image operations
virtual ImageD3D *createImage();
gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override;
gl::Error generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState) override;
virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
......
......@@ -35,8 +35,10 @@ class TextureStorage11 : public TextureStorage
virtual ~TextureStorage11();
static DWORD GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget);
static DWORD GetTextureMiscFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget, int levels);
UINT getBindFlags() const;
UINT getMiscFlags() const;
virtual gl::Error getResource(ID3D11Resource **outResource) = 0;
virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV);
......@@ -47,6 +49,7 @@ class TextureStorage11 : public TextureStorage
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
bool supportsNativeMipmapFunction() const override;
virtual int getLevelCount() const;
virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const;
......@@ -69,8 +72,10 @@ class TextureStorage11 : public TextureStorage
virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
gl::Error getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV);
protected:
TextureStorage11(Renderer11 *renderer, UINT bindFlags);
TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags);
int getLevelWidth(int mipLevel) const;
int getLevelHeight(int mipLevel) const;
int getLevelDepth(int mipLevel) const;
......@@ -120,6 +125,7 @@ class TextureStorage11 : public TextureStorage
private:
const UINT mBindFlags;
const UINT mMiscFlags;
struct SRVKey
{
......
......@@ -24,6 +24,7 @@ namespace d3d11
{
typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
typedef bool (*NativeMipmapGenerationSupportFunction)(D3D_FEATURE_LEVEL);
struct DXGIFormat
{
......@@ -51,6 +52,9 @@ struct DXGIFormat
ColorReadFunction colorReadFunction;
FastCopyFunctionMap fastCopyFunctions;
NativeMipmapGenerationSupportFunction nativeMipmapSupport;
ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
};
const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format);
......
......@@ -2846,6 +2846,12 @@ gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src)
return Image9::generateMipmap(dst9, src9);
}
gl::Error Renderer9::generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState)
{
UNREACHABLE();
return gl::Error(GL_NO_ERROR);
}
TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain)
{
SwapChain9 *swapChain9 = GetAs<SwapChain9>(swapChain);
......
......@@ -183,6 +183,7 @@ class Renderer9 : public RendererD3D
// Image operations
virtual ImageD3D *createImage();
gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override;
gl::Error generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState) override;
virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
......
......@@ -66,6 +66,11 @@ bool TextureStorage9::isManaged() const
return (mD3DPool == D3DPOOL_MANAGED);
}
bool TextureStorage9::supportsNativeMipmapFunction() const
{
return false;
}
D3DPOOL TextureStorage9::getPool() const
{
return mD3DPool;
......
......@@ -37,6 +37,7 @@ class TextureStorage9 : public TextureStorage
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
bool supportsNativeMipmapFunction() const override;
virtual int getLevelCount() const;
virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
......
......@@ -333,7 +333,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
return gl::Error(GL_NO_ERROR);
}
gl::Error TextureGL::generateMipmaps()
gl::Error TextureGL::generateMipmaps(const gl::SamplerState &samplerState)
{
mStateManager->bindTexture(mTextureType, mTextureID);
mFunctions->generateMipmap(mTextureType);
......
......@@ -43,7 +43,7 @@ class TextureGL : public TextureImpl
gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override;
gl::Error generateMipmaps() override;
gl::Error generateMipmaps(const gl::SamplerState &samplerState) override;
void bindTexImage(egl::Surface *surface) override;
void releaseTexImage() override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment