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 ...@@ -17,7 +17,13 @@ namespace rx
{ {
// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given. // 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) GLsizei samples)
: mWidth(width), : mWidth(width),
mHeight(height), mHeight(height),
...@@ -25,6 +31,8 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in ...@@ -25,6 +31,8 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in
mInternalFormat(internalFormat), mInternalFormat(internalFormat),
mD3DFormat(D3DFMT_UNKNOWN), mD3DFormat(D3DFMT_UNKNOWN),
mSamples(samples), mSamples(samples),
mTexture(texture),
mTextureLevel(textureLevel),
mRenderTarget(surface) mRenderTarget(surface)
{ {
ASSERT(mDepth == 1); ASSERT(mDepth == 1);
...@@ -39,6 +47,7 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in ...@@ -39,6 +47,7 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in
TextureRenderTarget9::~TextureRenderTarget9() TextureRenderTarget9::~TextureRenderTarget9()
{ {
SafeRelease(mTexture);
SafeRelease(mRenderTarget); SafeRelease(mRenderTarget);
} }
...@@ -67,7 +76,17 @@ GLsizei TextureRenderTarget9::getSamples() const ...@@ -67,7 +76,17 @@ GLsizei TextureRenderTarget9::getSamples() const
return mSamples; 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. // Caller is responsible for releasing the returned surface reference.
// TODO: remove the AddRef to match RenderTarget11 // TODO: remove the AddRef to match RenderTarget11
...@@ -120,11 +139,21 @@ GLsizei SurfaceRenderTarget9::getSamples() const ...@@ -120,11 +139,21 @@ GLsizei SurfaceRenderTarget9::getSamples() const
return 0; return 0;
} }
IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() const
{ {
return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget()); 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 D3DFORMAT SurfaceRenderTarget9::getD3DFormat() const
{ {
return d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat; return d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat;
......
...@@ -22,8 +22,12 @@ class RenderTarget9 : public RenderTargetD3D ...@@ -22,8 +22,12 @@ class RenderTarget9 : public RenderTargetD3D
public: public:
RenderTarget9() { } RenderTarget9() { }
virtual ~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; virtual D3DFORMAT getD3DFormat() const = 0;
}; };
...@@ -31,7 +35,13 @@ class RenderTarget9 : public RenderTargetD3D ...@@ -31,7 +35,13 @@ class RenderTarget9 : public RenderTargetD3D
class TextureRenderTarget9 : public RenderTarget9 class TextureRenderTarget9 : public RenderTarget9
{ {
public: 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); GLsizei samples);
virtual ~TextureRenderTarget9(); virtual ~TextureRenderTarget9();
...@@ -41,7 +51,9 @@ class TextureRenderTarget9 : public RenderTarget9 ...@@ -41,7 +51,9 @@ class TextureRenderTarget9 : public RenderTarget9
GLenum getInternalFormat() const override; GLenum getInternalFormat() const override;
GLsizei getSamples() 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; D3DFORMAT getD3DFormat() const override;
...@@ -53,6 +65,8 @@ class TextureRenderTarget9 : public RenderTarget9 ...@@ -53,6 +65,8 @@ class TextureRenderTarget9 : public RenderTarget9
D3DFORMAT mD3DFormat; D3DFORMAT mD3DFormat;
GLsizei mSamples; GLsizei mSamples;
IDirect3DBaseTexture9 *mTexture;
size_t mTextureLevel;
IDirect3DSurface9 *mRenderTarget; IDirect3DSurface9 *mRenderTarget;
}; };
...@@ -68,7 +82,9 @@ class SurfaceRenderTarget9 : public RenderTarget9 ...@@ -68,7 +82,9 @@ class SurfaceRenderTarget9 : public RenderTarget9
GLenum getInternalFormat() const override; GLenum getInternalFormat() const override;
GLsizei getSamples() 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; D3DFORMAT getD3DFormat() const override;
......
...@@ -2608,6 +2608,7 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL ...@@ -2608,6 +2608,7 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL
const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
GLuint supportedSamples = textureCaps.getNearestSamples(samples); GLuint supportedSamples = textureCaps.getNearestSamples(samples);
IDirect3DTexture9 *texture = nullptr;
IDirect3DSurface9 *renderTarget = NULL; IDirect3DSurface9 *renderTarget = NULL;
if (width > 0 && height > 0) if (width > 0 && height > 0)
{ {
...@@ -2623,10 +2624,23 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL ...@@ -2623,10 +2624,23 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL
} }
else else
{ {
requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != nullptr);
result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, if (supportedSamples > 0)
gl_d3d9::GetMultisampleType(supportedSamples), {
0, FALSE, &renderTarget, NULL); 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)) if (FAILED(result))
...@@ -2648,7 +2662,8 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL ...@@ -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); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -181,16 +181,24 @@ gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, Rende ...@@ -181,16 +181,24 @@ gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, Rende
if (!mRenderTarget && isRenderTarget()) if (!mRenderTarget && isRenderTarget())
{ {
IDirect3DBaseTexture9 *baseTexture = NULL;
gl::Error error = getBaseTexture(&baseTexture);
if (error.isError())
{
return error;
}
IDirect3DSurface9 *surface = NULL; 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()) if (error.isError())
{ {
return error; return error;
} }
mRenderTarget = baseTexture->AddRef();
new TextureRenderTarget9(surface, mInternalFormat, static_cast<GLsizei>(mTextureWidth), mRenderTarget = new TextureRenderTarget9(baseTexture, mTopLevel, surface, mInternalFormat,
static_cast<GLsizei>(mTextureHeight), 1, 0); static_cast<GLsizei>(mTextureWidth),
static_cast<GLsizei>(mTextureHeight), 1, 0);
} }
ASSERT(outRT); ASSERT(outRT);
...@@ -360,17 +368,25 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren ...@@ -360,17 +368,25 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren
if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget()) if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget())
{ {
IDirect3DBaseTexture9 *baseTexture = NULL;
gl::Error error = getBaseTexture(&baseTexture);
if (error.isError())
{
return error;
}
IDirect3DSurface9 *surface = NULL; IDirect3DSurface9 *surface = NULL;
gl::Error error = getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, error = getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex,
mTopLevel + index.mipIndex, false, &surface); mTopLevel + index.mipIndex, false, &surface);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
mRenderTarget[index.layerIndex] = baseTexture->AddRef();
new TextureRenderTarget9(surface, mInternalFormat, static_cast<GLsizei>(mTextureWidth), mRenderTarget[index.layerIndex] = new TextureRenderTarget9(
static_cast<GLsizei>(mTextureHeight), 1, 0); baseTexture, mTopLevel + index.mipIndex, surface, mInternalFormat,
static_cast<GLsizei>(mTextureWidth), static_cast<GLsizei>(mTextureHeight), 1, 0);
} }
*outRT = mRenderTarget[index.layerIndex]; *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