Commit 025e76a0 by Geoff Lang

When possible, create RenderTarget9s from textures.

Unless the RenderTarget9 is backed by a texture, it's not possible to sample from it. This is required to sample from D3D9 renderbuffers when they are bound to texture targets. BUG=angleproject:970 Change-Id: Id667a5e44c1f959609bc653a974ede5b93ec9a3e Reviewed-on: https://chromium-review.googlesource.com/293290Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 1528e56b
......@@ -17,7 +17,13 @@ namespace rx
{
// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given.
TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
TextureRenderTarget9::TextureRenderTarget9(IDirect3DBaseTexture9 *texture,
size_t textureLevel,
IDirect3DSurface9 *surface,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLsizei samples)
: mWidth(width),
mHeight(height),
......@@ -25,6 +31,8 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in
mInternalFormat(internalFormat),
mD3DFormat(D3DFMT_UNKNOWN),
mSamples(samples),
mTexture(texture),
mTextureLevel(textureLevel),
mRenderTarget(surface)
{
ASSERT(mDepth == 1);
......@@ -39,6 +47,7 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in
TextureRenderTarget9::~TextureRenderTarget9()
{
SafeRelease(mTexture);
SafeRelease(mRenderTarget);
}
......@@ -67,7 +76,17 @@ GLsizei TextureRenderTarget9::getSamples() const
return mSamples;
}
IDirect3DSurface9 *TextureRenderTarget9::getSurface()
IDirect3DBaseTexture9 *TextureRenderTarget9::getTexture() const
{
return mTexture;
}
size_t TextureRenderTarget9::getTextureLevel() const
{
return mTextureLevel;
}
IDirect3DSurface9 *TextureRenderTarget9::getSurface() const
{
// Caller is responsible for releasing the returned surface reference.
// TODO: remove the AddRef to match RenderTarget11
......@@ -120,11 +139,21 @@ GLsizei SurfaceRenderTarget9::getSamples() const
return 0;
}
IDirect3DSurface9 *SurfaceRenderTarget9::getSurface()
IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() const
{
return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget());
}
IDirect3DBaseTexture9 *SurfaceRenderTarget9::getTexture() const
{
return (mDepth ? nullptr : mSwapChain->getOffscreenTexture());
}
size_t SurfaceRenderTarget9::getTextureLevel() const
{
return 0;
}
D3DFORMAT SurfaceRenderTarget9::getD3DFormat() const
{
return d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat;
......
......@@ -22,8 +22,12 @@ class RenderTarget9 : public RenderTargetD3D
public:
RenderTarget9() { }
virtual ~RenderTarget9() { }
// Retrieve the texture that backs this render target, may be null for swap chain render
// targets.
virtual IDirect3DBaseTexture9 *getTexture() const = 0;
virtual size_t getTextureLevel() const = 0;
virtual IDirect3DSurface9 *getSurface() = 0;
virtual IDirect3DSurface9 *getSurface() const = 0;
virtual D3DFORMAT getD3DFormat() const = 0;
};
......@@ -31,7 +35,13 @@ class RenderTarget9 : public RenderTargetD3D
class TextureRenderTarget9 : public RenderTarget9
{
public:
TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
TextureRenderTarget9(IDirect3DBaseTexture9 *texture,
size_t textureLevel,
IDirect3DSurface9 *surface,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLsizei samples);
virtual ~TextureRenderTarget9();
......@@ -41,7 +51,9 @@ class TextureRenderTarget9 : public RenderTarget9
GLenum getInternalFormat() const override;
GLsizei getSamples() const override;
IDirect3DSurface9 *getSurface() override;
IDirect3DBaseTexture9 *getTexture() const override;
size_t getTextureLevel() const override;
IDirect3DSurface9 *getSurface() const override;
D3DFORMAT getD3DFormat() const override;
......@@ -53,6 +65,8 @@ class TextureRenderTarget9 : public RenderTarget9
D3DFORMAT mD3DFormat;
GLsizei mSamples;
IDirect3DBaseTexture9 *mTexture;
size_t mTextureLevel;
IDirect3DSurface9 *mRenderTarget;
};
......@@ -68,7 +82,9 @@ class SurfaceRenderTarget9 : public RenderTarget9
GLenum getInternalFormat() const override;
GLsizei getSamples() const override;
IDirect3DSurface9 *getSurface() override;
IDirect3DBaseTexture9 *getTexture() const override;
size_t getTextureLevel() const override;
IDirect3DSurface9 *getSurface() const override;
D3DFORMAT getD3DFormat() const override;
......
......@@ -2608,6 +2608,7 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL
const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
GLuint supportedSamples = textureCaps.getNearestSamples(samples);
IDirect3DTexture9 *texture = nullptr;
IDirect3DSurface9 *renderTarget = NULL;
if (width > 0 && height > 0)
{
......@@ -2623,10 +2624,23 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL
}
else
{
requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
gl_d3d9::GetMultisampleType(supportedSamples),
0, FALSE, &renderTarget, NULL);
requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != nullptr);
if (supportedSamples > 0)
{
result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
gl_d3d9::GetMultisampleType(supportedSamples),
0, FALSE, &renderTarget, nullptr);
}
else
{
result = mDevice->CreateTexture(
width, height, 1, D3DUSAGE_RENDERTARGET, d3d9FormatInfo.texFormat,
getTexturePool(D3DUSAGE_RENDERTARGET), &texture, nullptr);
if (!FAILED(result))
{
result = texture->GetSurfaceLevel(0, &renderTarget);
}
}
}
if (FAILED(result))
......@@ -2648,7 +2662,8 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL
}
}
*outRT = new TextureRenderTarget9(renderTarget, format, width, height, 1, supportedSamples);
*outRT = new TextureRenderTarget9(texture, 0, renderTarget, format, width, height, 1,
supportedSamples);
return gl::Error(GL_NO_ERROR);
}
......
......@@ -181,16 +181,24 @@ gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, Rende
if (!mRenderTarget && isRenderTarget())
{
IDirect3DBaseTexture9 *baseTexture = NULL;
gl::Error error = getBaseTexture(&baseTexture);
if (error.isError())
{
return error;
}
IDirect3DSurface9 *surface = NULL;
gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, false, &surface);
error = getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, false, &surface);
if (error.isError())
{
return error;
}
mRenderTarget =
new TextureRenderTarget9(surface, mInternalFormat, static_cast<GLsizei>(mTextureWidth),
static_cast<GLsizei>(mTextureHeight), 1, 0);
baseTexture->AddRef();
mRenderTarget = new TextureRenderTarget9(baseTexture, mTopLevel, surface, mInternalFormat,
static_cast<GLsizei>(mTextureWidth),
static_cast<GLsizei>(mTextureHeight), 1, 0);
}
ASSERT(outRT);
......@@ -360,17 +368,25 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren
if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget())
{
IDirect3DBaseTexture9 *baseTexture = NULL;
gl::Error error = getBaseTexture(&baseTexture);
if (error.isError())
{
return error;
}
IDirect3DSurface9 *surface = NULL;
gl::Error error = getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex,
mTopLevel + index.mipIndex, false, &surface);
error = getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex,
mTopLevel + index.mipIndex, false, &surface);
if (error.isError())
{
return error;
}
mRenderTarget[index.layerIndex] =
new TextureRenderTarget9(surface, mInternalFormat, static_cast<GLsizei>(mTextureWidth),
static_cast<GLsizei>(mTextureHeight), 1, 0);
baseTexture->AddRef();
mRenderTarget[index.layerIndex] = new TextureRenderTarget9(
baseTexture, mTopLevel + index.mipIndex, surface, mInternalFormat,
static_cast<GLsizei>(mTextureWidth), static_cast<GLsizei>(mTextureHeight), 1, 0);
}
*outRT = mRenderTarget[index.layerIndex];
......
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