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 ...@@ -277,7 +277,7 @@ Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, c
Error Texture::generateMipmaps() Error Texture::generateMipmaps()
{ {
Error error = mTexture->generateMipmaps(); Error error = mTexture->generateMipmaps(getSamplerState());
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -60,7 +60,7 @@ class TextureImpl : angle::NonCopyable ...@@ -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 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 bindTexImage(egl::Surface *surface) = 0;
virtual void releaseTexImage() = 0; virtual void releaseTexImage() = 0;
......
...@@ -163,6 +163,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -163,6 +163,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
// Image operations // Image operations
virtual ImageD3D *createImage() = 0; virtual ImageD3D *createImage() = 0;
virtual gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) = 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(SwapChainD3D *swapChain) = 0;
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) = 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; virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) = 0;
......
...@@ -376,7 +376,7 @@ ImageD3D *TextureD3D::getBaseLevelImage() const ...@@ -376,7 +376,7 @@ ImageD3D *TextureD3D::getBaseLevelImage() const
return getImage(getImageIndex(0, 0)); return getImage(getImageIndex(0, 0));
} }
gl::Error TextureD3D::generateMipmaps() gl::Error TextureD3D::generateMipmaps(const gl::SamplerState &samplerState)
{ {
GLint mipCount = mipLevels(); GLint mipCount = mipLevels();
...@@ -405,6 +405,38 @@ gl::Error TextureD3D::generateMipmaps() ...@@ -405,6 +405,38 @@ gl::Error TextureD3D::generateMipmaps()
// Set up proper mipmap chain in our Image array. // Set up proper mipmap chain in our Image array.
initMipmapsImages(); 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 // We know that all layers have the same dimension, for the texture to be complete
GLint layerCount = static_cast<GLint>(getLayerCount(0)); GLint layerCount = static_cast<GLint>(getLayerCount(0));
......
...@@ -60,7 +60,7 @@ class TextureD3D : public TextureImpl ...@@ -60,7 +60,7 @@ class TextureD3D : public TextureImpl
virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0; virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0;
virtual bool isValidIndex(const gl::ImageIndex &index) 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(); TextureStorage *getStorage();
ImageD3D *getBaseLevelImage() const; ImageD3D *getBaseLevelImage() const;
...@@ -106,6 +106,8 @@ class TextureD3D : public TextureImpl ...@@ -106,6 +106,8 @@ class TextureD3D : public TextureImpl
virtual gl::Error updateStorage() = 0; virtual gl::Error updateStorage() = 0;
bool shouldUseSetData(const ImageD3D *image) const; bool shouldUseSetData(const ImageD3D *image) const;
gl::Error generateMipmapsUsingImages();
}; };
class TextureD3D_2D : public TextureD3D class TextureD3D_2D : public TextureD3D
......
...@@ -39,6 +39,7 @@ class TextureStorage : angle::NonCopyable ...@@ -39,6 +39,7 @@ class TextureStorage : angle::NonCopyable
virtual int getTopLevel() const = 0; virtual int getTopLevel() const = 0;
virtual bool isRenderTarget() const = 0; virtual bool isRenderTarget() const = 0;
virtual bool isManaged() const = 0; virtual bool isManaged() const = 0;
virtual bool supportsNativeMipmapFunction() const = 0;
virtual int getLevelCount() const = 0; virtual int getLevelCount() const = 0;
virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0;
......
...@@ -3070,6 +3070,25 @@ gl::Error Renderer11::generateMipmap(ImageD3D *dest, ImageD3D *src) ...@@ -3070,6 +3070,25 @@ gl::Error Renderer11::generateMipmap(ImageD3D *dest, ImageD3D *src)
return Image11::generateMipmap(dest11, src11); 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) TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain)
{ {
SwapChain11 *swapChain11 = GetAs<SwapChain11>(swapChain); SwapChain11 *swapChain11 = GetAs<SwapChain11>(swapChain);
......
...@@ -185,6 +185,7 @@ class Renderer11 : public RendererD3D ...@@ -185,6 +185,7 @@ class Renderer11 : public RendererD3D
// Image operations // Image operations
virtual ImageD3D *createImage(); virtual ImageD3D *createImage();
gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; 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(SwapChainD3D *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly); 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); virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
......
...@@ -35,8 +35,10 @@ class TextureStorage11 : public TextureStorage ...@@ -35,8 +35,10 @@ class TextureStorage11 : public TextureStorage
virtual ~TextureStorage11(); virtual ~TextureStorage11();
static DWORD GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget); 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 getBindFlags() const;
UINT getMiscFlags() const;
virtual gl::Error getResource(ID3D11Resource **outResource) = 0; virtual gl::Error getResource(ID3D11Resource **outResource) = 0;
virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV); virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV);
...@@ -47,6 +49,7 @@ class TextureStorage11 : public TextureStorage ...@@ -47,6 +49,7 @@ class TextureStorage11 : public TextureStorage
virtual int getTopLevel() const; virtual int getTopLevel() const;
virtual bool isRenderTarget() const; virtual bool isRenderTarget() const;
virtual bool isManaged() const; virtual bool isManaged() const;
bool supportsNativeMipmapFunction() const override;
virtual int getLevelCount() const; virtual int getLevelCount() const;
virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const; virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const;
...@@ -69,8 +72,10 @@ class TextureStorage11 : public TextureStorage ...@@ -69,8 +72,10 @@ class TextureStorage11 : public TextureStorage
virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData); const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
gl::Error getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV);
protected: protected:
TextureStorage11(Renderer11 *renderer, UINT bindFlags); TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags);
int getLevelWidth(int mipLevel) const; int getLevelWidth(int mipLevel) const;
int getLevelHeight(int mipLevel) const; int getLevelHeight(int mipLevel) const;
int getLevelDepth(int mipLevel) const; int getLevelDepth(int mipLevel) const;
...@@ -120,6 +125,7 @@ class TextureStorage11 : public TextureStorage ...@@ -120,6 +125,7 @@ class TextureStorage11 : public TextureStorage
private: private:
const UINT mBindFlags; const UINT mBindFlags;
const UINT mMiscFlags;
struct SRVKey struct SRVKey
{ {
......
...@@ -24,6 +24,7 @@ namespace d3d11 ...@@ -24,6 +24,7 @@ namespace d3d11
{ {
typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap; typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
typedef bool (*NativeMipmapGenerationSupportFunction)(D3D_FEATURE_LEVEL);
struct DXGIFormat struct DXGIFormat
{ {
...@@ -51,6 +52,9 @@ struct DXGIFormat ...@@ -51,6 +52,9 @@ struct DXGIFormat
ColorReadFunction colorReadFunction; ColorReadFunction colorReadFunction;
FastCopyFunctionMap fastCopyFunctions; FastCopyFunctionMap fastCopyFunctions;
NativeMipmapGenerationSupportFunction nativeMipmapSupport;
ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
}; };
const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format); const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format);
......
...@@ -2846,6 +2846,12 @@ gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src) ...@@ -2846,6 +2846,12 @@ gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src)
return Image9::generateMipmap(dst9, src9); 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) TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain)
{ {
SwapChain9 *swapChain9 = GetAs<SwapChain9>(swapChain); SwapChain9 *swapChain9 = GetAs<SwapChain9>(swapChain);
......
...@@ -183,6 +183,7 @@ class Renderer9 : public RendererD3D ...@@ -183,6 +183,7 @@ class Renderer9 : public RendererD3D
// Image operations // Image operations
virtual ImageD3D *createImage(); virtual ImageD3D *createImage();
gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; 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(SwapChainD3D *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly); 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); virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
......
...@@ -66,6 +66,11 @@ bool TextureStorage9::isManaged() const ...@@ -66,6 +66,11 @@ bool TextureStorage9::isManaged() const
return (mD3DPool == D3DPOOL_MANAGED); return (mD3DPool == D3DPOOL_MANAGED);
} }
bool TextureStorage9::supportsNativeMipmapFunction() const
{
return false;
}
D3DPOOL TextureStorage9::getPool() const D3DPOOL TextureStorage9::getPool() const
{ {
return mD3DPool; return mD3DPool;
......
...@@ -37,6 +37,7 @@ class TextureStorage9 : public TextureStorage ...@@ -37,6 +37,7 @@ class TextureStorage9 : public TextureStorage
virtual int getTopLevel() const; virtual int getTopLevel() const;
virtual bool isRenderTarget() const; virtual bool isRenderTarget() const;
virtual bool isManaged() const; virtual bool isManaged() const;
bool supportsNativeMipmapFunction() const override;
virtual int getLevelCount() const; virtual int getLevelCount() const;
virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, 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 ...@@ -333,7 +333,7 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error TextureGL::generateMipmaps() gl::Error TextureGL::generateMipmaps(const gl::SamplerState &samplerState)
{ {
mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindTexture(mTextureType, mTextureID);
mFunctions->generateMipmap(mTextureType); mFunctions->generateMipmap(mTextureType);
......
...@@ -43,7 +43,7 @@ class TextureGL : public TextureImpl ...@@ -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 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 bindTexImage(egl::Surface *surface) override;
void releaseTexImage() 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