Commit bc21e18b by Olli Etuaho

D3D11 Texture refactoring: Store ANGLEFormat in TextureStorage11

This is needed to enable removing GetDXGIFormatInfo calls, which are difficult to use correctly due to a texture format being associated with multiple DXGI formats. This is done in preparation of changing some of the DXGI formats associated with integer textures. BUG=angleproject:1244 TEST=angle_end2end_tests, dEQP-GLES3.functional.fbo.* (no regressions) Change-Id: I992c4c06189887c1b9de02f9b63dd9a474fcffab Reviewed-on: https://chromium-review.googlesource.com/329094Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 0011bb60
......@@ -178,7 +178,7 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth
return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
}
RenderTarget11::RenderTarget11()
RenderTarget11::RenderTarget11(d3d11::ANGLEFormat angleFormat) : mANGLEFormat(angleFormat)
{
}
......@@ -211,9 +211,17 @@ void RenderTarget11::signalDirty()
mDirtyCallbacks.clear();
}
TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples)
: mWidth(width),
TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv,
ID3D11Resource *resource,
ID3D11ShaderResourceView *srv,
GLenum internalFormat,
d3d11::ANGLEFormat angleFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLsizei samples)
: RenderTarget11(angleFormat),
mWidth(width),
mHeight(height),
mDepth(depth),
mInternalFormat(internalFormat),
......@@ -248,11 +256,20 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11
mRenderTarget->GetDesc(&desc);
mDXGIFormat = desc.Format;
}
}
TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples)
: mWidth(width),
ASSERT(mANGLEFormat != d3d11::ANGLE_FORMAT_NONE || mWidth == 0 || mHeight == 0);
}
TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv,
ID3D11Resource *resource,
ID3D11ShaderResourceView *srv,
GLenum internalFormat,
d3d11::ANGLEFormat angleFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLsizei samples)
: RenderTarget11(angleFormat),
mWidth(width),
mHeight(height),
mDepth(depth),
mInternalFormat(internalFormat),
......@@ -287,6 +304,7 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11
mDepthStencil->GetDesc(&desc);
mDXGIFormat = desc.Format;
}
ASSERT(mANGLEFormat != d3d11::ANGLE_FORMAT_NONE || mWidth == 0 || mHeight == 0);
}
TextureRenderTarget11::~TextureRenderTarget11()
......@@ -352,12 +370,19 @@ DXGI_FORMAT TextureRenderTarget11::getDXGIFormat() const
return mDXGIFormat;
}
SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth)
: mSwapChain(swapChain),
SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain,
Renderer11 *renderer,
bool depth)
: RenderTarget11(d3d11::ANGLE_FORMAT_NONE), // format will be determined in constructor body
mSwapChain(swapChain),
mRenderer(renderer),
mDepth(depth)
{
ASSERT(mSwapChain);
mANGLEFormat = d3d11::GetTextureFormatInfo(getInternalFormatInternal(),
mRenderer->getRenderer11DeviceCaps())
.formatSet.format;
}
SurfaceRenderTarget11::~SurfaceRenderTarget11()
......@@ -381,6 +406,11 @@ GLsizei SurfaceRenderTarget11::getDepth() const
GLenum SurfaceRenderTarget11::getInternalFormat() const
{
return getInternalFormatInternal();
}
GLenum SurfaceRenderTarget11::getInternalFormatInternal() const
{
return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat());
}
......@@ -407,7 +437,8 @@ ID3D11DepthStencilView *SurfaceRenderTarget11::getDepthStencilView() const
ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const
{
return (mDepth ? mSwapChain->getDepthStencilShaderResource() : mSwapChain->getRenderTargetShaderResource());
return (mDepth ? mSwapChain->getDepthStencilShaderResource()
: mSwapChain->getRenderTargetShaderResource());
}
unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
......
......@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_
#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
......@@ -22,7 +23,7 @@ class Renderer11;
class RenderTarget11 : public RenderTargetD3D
{
public:
RenderTarget11();
RenderTarget11(d3d11::ANGLEFormat angleFormat);
virtual ~RenderTarget11();
virtual ID3D11Resource *getTexture() const = 0;
......@@ -38,18 +39,36 @@ class RenderTarget11 : public RenderTargetD3D
void removeDirtyCallback(const NotificationCallback *callback);
void signalDirty() override;
d3d11::ANGLEFormat getANGLEFormat() const { return mANGLEFormat; }
protected:
std::set<const NotificationCallback *> mDirtyCallbacks;
d3d11::ANGLEFormat mANGLEFormat;
};
class TextureRenderTarget11 : public RenderTarget11
{
public:
// TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them
TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples);
TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples);
TextureRenderTarget11(ID3D11RenderTargetView *rtv,
ID3D11Resource *resource,
ID3D11ShaderResourceView *srv,
GLenum internalFormat,
d3d11::ANGLEFormat angleFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLsizei samples);
TextureRenderTarget11(ID3D11DepthStencilView *dsv,
ID3D11Resource *resource,
ID3D11ShaderResourceView *srv,
GLenum internalFormat,
d3d11::ANGLEFormat angleFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLsizei samples);
virtual ~TextureRenderTarget11();
GLsizei getWidth() const override;
......@@ -104,6 +123,10 @@ class SurfaceRenderTarget11 : public RenderTarget11
DXGI_FORMAT getDXGIFormat() const override;
private:
// The internal versions of the functions are needed so that they can be safely called
// from the constructor.
GLenum getInternalFormatInternal() const;
SwapChain11 *mSwapChain;
Renderer11 *mRenderer;
bool mDepth;
......
......@@ -3131,7 +3131,9 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result);
}
*outRT = new TextureRenderTarget11(dsv, texture, srv, format, width, height, 1, supportedSamples);
*outRT =
new TextureRenderTarget11(dsv, texture, srv, format, formatInfo.formatSet.format,
width, height, 1, supportedSamples);
SafeRelease(dsv);
}
......@@ -3158,7 +3160,9 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
mDeviceContext->ClearRenderTargetView(rtv, clearValues);
}
*outRT = new TextureRenderTarget11(rtv, texture, srv, format, width, height, 1, supportedSamples);
*outRT =
new TextureRenderTarget11(rtv, texture, srv, format, formatInfo.formatSet.format,
width, height, 1, supportedSamples);
SafeRelease(rtv);
}
......@@ -3172,7 +3176,9 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
}
else
{
*outRT = new TextureRenderTarget11(reinterpret_cast<ID3D11RenderTargetView*>(NULL), NULL, NULL, format, width, height, 1, supportedSamples);
*outRT = new TextureRenderTarget11(reinterpret_cast<ID3D11RenderTargetView *>(nullptr),
nullptr, nullptr, format, d3d11::ANGLE_FORMAT_NONE,
width, height, 1, supportedSamples);
}
return gl::Error(GL_NO_ERROR);
......
......@@ -136,7 +136,8 @@ bool SupportsFormat(const Renderer11DeviceCaps &deviceCaps)
}} // namespace
ANGLEFormatSet::ANGLEFormatSet()
: texFormat(DXGI_FORMAT_UNKNOWN),
: format(ANGLE_FORMAT_NONE),
texFormat(DXGI_FORMAT_UNKNOWN),
srvFormat(DXGI_FORMAT_UNKNOWN),
rtvFormat(DXGI_FORMAT_UNKNOWN),
dsvFormat(DXGI_FORMAT_UNKNOWN),
......@@ -149,10 +150,11 @@ ANGLEFormatSet::ANGLEFormatSet()
// This function allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and
// DSVs given a GL internal format.
TextureFormat::TextureFormat(GLenum internalFormat,
const ANGLEFormatSet &formatSet,
const ANGLEFormat angleFormat,
InitializeTextureDataFunction internalFormatInitializer)
: formatSet(formatSet), dataInitializerFunction(internalFormatInitializer)
: dataInitializerFunction(internalFormatInitializer)
{{
formatSet = GetANGLEFormatSet(angleFormat);
swizzleFormatSet = GetANGLEFormatSet(formatSet.swizzleFormat);
// Gather all the load functions for this internal format
......@@ -161,12 +163,14 @@ TextureFormat::TextureFormat(GLenum internalFormat,
ASSERT(loadFunctions.size() != 0 || internalFormat == GL_NONE);
}}
ANGLEFormatSet::ANGLEFormatSet(DXGI_FORMAT texFormat,
ANGLEFormatSet::ANGLEFormatSet(ANGLEFormat format,
DXGI_FORMAT texFormat,
DXGI_FORMAT srvFormat,
DXGI_FORMAT rtvFormat,
DXGI_FORMAT dsvFormat,
ANGLEFormat swizzleFormat)
: texFormat(texFormat),
: format(format),
texFormat(texFormat),
srvFormat(srvFormat),
rtvFormat(rtvFormat),
dsvFormat(dsvFormat),
......@@ -202,7 +206,7 @@ const TextureFormat &GetTextureFormatInfo(GLenum internalFormat,
}}
// clang-format on
static const TextureFormat defaultInfo(GL_NONE, ANGLEFormatSet(), nullptr);
static const TextureFormat defaultInfo(GL_NONE, ANGLE_FORMAT_NONE, nullptr);
return defaultInfo;
}} // GetTextureFormatInfo
......@@ -347,7 +351,7 @@ def get_texture_format_item(idx, internal_format, requirements_fn, angle_format_
indent += ' '
table_data += indent + 'static const TextureFormat textureFormat(internalFormat,\n'
table_data += indent + ' GetANGLEFormatSet(' + angle_format_id + '),\n'
table_data += indent + ' ' + angle_format_id + ',\n'
table_data += indent + ' ' + internal_format_initializer + ');\n'
table_data += indent + 'return textureFormat;\n'
......@@ -392,7 +396,8 @@ def parse_json_into_switch_angle_format_string(json_data):
dsv_format = angle_format["dsvFormat"] if "dsvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
swizzle_format = get_swizzle_format_id(angle_format_item[0], angle_format)
table_data += ' {\n'
table_data += ' static const ANGLEFormatSet formatInfo(' + tex_format + ',\n'
table_data += ' static const ANGLEFormatSet formatInfo(' + angle_format_item[0] + ',\n'
table_data += ' ' + tex_format + ',\n'
table_data += ' ' + srv_format + ',\n'
table_data += ' ' + rtv_format + ',\n'
table_data += ' ' + dsv_format + ',\n'
......@@ -431,7 +436,9 @@ with open('texture_format_map.json') as texture_format_map_file:
texture_format_cases = parse_json_into_switch_texture_format_string(json_map, json_data)
angle_format_cases = parse_json_into_switch_angle_format_string(json_data)
output_cpp = template_texture_format_table_autogen_cpp.format(texture_format_info_cases=texture_format_cases, angle_format_info_cases=angle_format_cases)
output_cpp = template_texture_format_table_autogen_cpp.format(
texture_format_info_cases=texture_format_cases,
angle_format_info_cases=angle_format_cases)
with open('texture_format_table_autogen.cpp', 'wt') as out_file:
out_file.write(output_cpp)
out_file.close()
......
......@@ -38,7 +38,8 @@ struct LoadImageFunctionInfo
struct ANGLEFormatSet
{
ANGLEFormatSet();
ANGLEFormatSet(DXGI_FORMAT texFormat,
ANGLEFormatSet(ANGLEFormat format,
DXGI_FORMAT texFormat,
DXGI_FORMAT srvFormat,
DXGI_FORMAT rtvFormat,
DXGI_FORMAT dsvFormat,
......@@ -46,6 +47,8 @@ struct ANGLEFormatSet
ANGLEFormatSet(const ANGLEFormatSet &) = default;
ANGLEFormatSet &operator=(const ANGLEFormatSet &) = default;
ANGLEFormat format;
DXGI_FORMAT texFormat;
DXGI_FORMAT srvFormat;
DXGI_FORMAT rtvFormat;
......@@ -57,7 +60,7 @@ struct ANGLEFormatSet
struct TextureFormat : public angle::NonCopyable
{
TextureFormat(GLenum internalFormat,
const ANGLEFormatSet &formatSet,
const ANGLEFormat angleFormat,
InitializeTextureDataFunction internalFormatInitializer);
ANGLEFormatSet formatSet;
......
......@@ -124,6 +124,16 @@ class FramebufferFormatsTest : public ANGLETest
EXPECT_GL_NO_ERROR();
}
void testZeroHeightRenderbuffer()
{
glGenRenderbuffers(1, &mRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
mRenderbuffer);
EXPECT_GL_NO_ERROR();
}
void SetUp() override
{
ANGLETest::SetUp();
......@@ -303,6 +313,18 @@ TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
}
// Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts.
TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
{
if (getClientVersion() < 3)
{
std::cout << "Test skipped due to missing ES3" << std::endl;
return;
}
testZeroHeightRenderbuffer();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(FramebufferFormatsTest,
......
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