Commit 7b591905 by Olli Etuaho Committed by Commit Bot

D3D11: Use blit SRV format for blits

blitSRVFormat stores the format that is used with ANGLE's internal blit shaders. By default, it is the same as the normal SRV format. For integer textures with a red channel, the RTV format is used instead. This makes it possible to change the storage format and the SRV format for the integer textures without affecting the blit format. The blitSRVFormat is used when doing blits in Blit11::copyTexture(). An exception is made for depth/stencil renderbuffer blit - in these cases it is okay to assume that the regular SRV format works for blitting. In the future the regular SRV format for integer textures will be changed to be different from their blit SRV format. TEST=angle_end2end_tests dEQP-GLES3.functional.fbo.blit.* (no regression) dEQP-GLES3.functional.texture.swizzle.* (no regression) BUG=angleproject:1244 Change-Id: Ie0e790e58ec054b64ef5983a09dbfc7754f269ca Reviewed-on: https://chromium-review.googlesource.com/327104Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 84c9f593
......@@ -208,6 +208,7 @@ void RenderTarget11::signalDirty()
TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv,
ID3D11Resource *resource,
ID3D11ShaderResourceView *srv,
ID3D11ShaderResourceView *blitSRV,
GLenum internalFormat,
d3d11::ANGLEFormat angleFormat,
GLsizei width,
......@@ -224,7 +225,8 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv,
mTexture(resource),
mRenderTarget(rtv),
mDepthStencil(NULL),
mShaderResource(srv)
mShaderResource(srv),
mBlitShaderResource(blitSRV)
{
if (mTexture)
{
......@@ -241,6 +243,11 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv,
mShaderResource->AddRef();
}
if (mBlitShaderResource)
{
mBlitShaderResource->AddRef();
}
if (mRenderTarget && mTexture)
{
mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
......@@ -267,7 +274,8 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv,
mTexture(resource),
mRenderTarget(NULL),
mDepthStencil(dsv),
mShaderResource(srv)
mShaderResource(srv),
mBlitShaderResource(nullptr)
{
if (mTexture)
{
......@@ -297,6 +305,7 @@ TextureRenderTarget11::~TextureRenderTarget11()
SafeRelease(mRenderTarget);
SafeRelease(mDepthStencil);
SafeRelease(mShaderResource);
SafeRelease(mBlitShaderResource);
}
ID3D11Resource *TextureRenderTarget11::getTexture() const
......@@ -319,6 +328,11 @@ ID3D11ShaderResourceView *TextureRenderTarget11::getShaderResourceView() const
return mShaderResource;
}
ID3D11ShaderResourceView *TextureRenderTarget11::getBlitShaderResourceView() const
{
return mBlitShaderResource;
}
GLsizei TextureRenderTarget11::getWidth() const
{
return mWidth;
......@@ -420,6 +434,12 @@ ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const
: mSwapChain->getRenderTargetShaderResource());
}
ID3D11ShaderResourceView *SurfaceRenderTarget11::getBlitShaderResourceView() const
{
// The SurfaceRenderTargetView format should always be such that the normal SRV works for blits.
return getShaderResourceView();
}
unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
{
return 0;
......
......@@ -30,6 +30,7 @@ class RenderTarget11 : public RenderTargetD3D
virtual ID3D11RenderTargetView *getRenderTargetView() const = 0;
virtual ID3D11DepthStencilView *getDepthStencilView() const = 0;
virtual ID3D11ShaderResourceView *getShaderResourceView() const = 0;
virtual ID3D11ShaderResourceView *getBlitShaderResourceView() const = 0;
virtual unsigned int getSubresourceIndex() const = 0;
......@@ -51,6 +52,7 @@ class TextureRenderTarget11 : public RenderTarget11
TextureRenderTarget11(ID3D11RenderTargetView *rtv,
ID3D11Resource *resource,
ID3D11ShaderResourceView *srv,
ID3D11ShaderResourceView *blitSRV,
GLenum internalFormat,
d3d11::ANGLEFormat angleFormat,
GLsizei width,
......@@ -78,6 +80,7 @@ class TextureRenderTarget11 : public RenderTarget11
ID3D11RenderTargetView *getRenderTargetView() const override;
ID3D11DepthStencilView *getDepthStencilView() const override;
ID3D11ShaderResourceView *getShaderResourceView() const override;
ID3D11ShaderResourceView *getBlitShaderResourceView() const override;
unsigned int getSubresourceIndex() const override;
......@@ -93,6 +96,10 @@ class TextureRenderTarget11 : public RenderTarget11
ID3D11RenderTargetView *mRenderTarget;
ID3D11DepthStencilView *mDepthStencil;
ID3D11ShaderResourceView *mShaderResource;
// Shader resource view to use with internal blit shaders. Not set for depth/stencil render
// targets.
ID3D11ShaderResourceView *mBlitShaderResource;
};
class SurfaceRenderTarget11 : public RenderTarget11
......@@ -111,6 +118,7 @@ class SurfaceRenderTarget11 : public RenderTarget11
ID3D11RenderTargetView *getRenderTargetView() const override;
ID3D11DepthStencilView *getDepthStencilView() const override;
ID3D11ShaderResourceView *getShaderResourceView() const override;
ID3D11ShaderResourceView *getBlitShaderResourceView() const override;
unsigned int getSubresourceIndex() const override;
......
......@@ -2823,7 +2823,7 @@ gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::
}
ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
ID3D11ShaderResourceView *source = sourceRenderTarget->getBlitShaderResourceView();
ASSERT(source);
TextureStorage11_2D *storage11 = GetAs<TextureStorage11_2D>(storage);
......@@ -2882,7 +2882,7 @@ gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl
}
ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
ID3D11ShaderResourceView *source = sourceRenderTarget->getBlitShaderResourceView();
ASSERT(source);
TextureStorage11_Cube *storage11 = GetAs<TextureStorage11_Cube>(storage);
......@@ -2941,7 +2941,7 @@ gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::
}
ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
ID3D11ShaderResourceView *source = sourceRenderTarget->getBlitShaderResourceView();
ASSERT(source);
TextureStorage11_3D *storage11 = GetAs<TextureStorage11_3D>(storage);
......@@ -2993,7 +2993,7 @@ gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const
}
ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
ID3D11ShaderResourceView *source = sourceRenderTarget->getBlitShaderResourceView();
ASSERT(source);
TextureStorage11_2DArray *storage11 = GetAs<TextureStorage11_2DArray>(storage);
......@@ -3083,7 +3083,8 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target texture, result: 0x%X.", result);
}
ID3D11ShaderResourceView *srv = NULL;
ID3D11ShaderResourceView *srv = nullptr;
ID3D11ShaderResourceView *blitSRV = nullptr;
if (bindSRV)
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
......@@ -3099,6 +3100,34 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
SafeRelease(texture);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result);
}
if (formatInfo.formatSet.blitSRVFormat != formatInfo.formatSet.srvFormat)
{
D3D11_SHADER_RESOURCE_VIEW_DESC blitSRVDesc;
blitSRVDesc.Format = formatInfo.formatSet.blitSRVFormat;
blitSRVDesc.ViewDimension = (supportedSamples == 0)
? D3D11_SRV_DIMENSION_TEXTURE2D
: D3D11_SRV_DIMENSION_TEXTURE2DMS;
blitSRVDesc.Texture2D.MostDetailedMip = 0;
blitSRVDesc.Texture2D.MipLevels = 1;
result = mDevice->CreateShaderResourceView(texture, &blitSRVDesc, &blitSRV);
if (FAILED(result))
{
ASSERT(result == E_OUTOFMEMORY);
SafeRelease(texture);
SafeRelease(srv);
return gl::Error(GL_OUT_OF_MEMORY,
"Failed to create render target shader resource view for "
"blits, result: 0x%X.",
result);
}
}
else
{
blitSRV = srv;
srv->AddRef();
}
}
if (bindDSV)
......@@ -3116,6 +3145,7 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
ASSERT(result == E_OUTOFMEMORY);
SafeRelease(texture);
SafeRelease(srv);
SafeRelease(blitSRV);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result);
}
......@@ -3139,6 +3169,7 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
ASSERT(result == E_OUTOFMEMORY);
SafeRelease(texture);
SafeRelease(srv);
SafeRelease(blitSRV);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target render target view, result: 0x%X.", result);
}
......@@ -3148,9 +3179,9 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
mDeviceContext->ClearRenderTargetView(rtv, clearValues);
}
*outRT =
new TextureRenderTarget11(rtv, texture, srv, format, formatInfo.formatSet.format,
width, height, 1, supportedSamples);
*outRT = new TextureRenderTarget11(rtv, texture, srv, blitSRV, format,
formatInfo.formatSet.format, width, height, 1,
supportedSamples);
SafeRelease(rtv);
}
......@@ -3161,12 +3192,13 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
SafeRelease(texture);
SafeRelease(srv);
SafeRelease(blitSRV);
}
else
{
*outRT = new TextureRenderTarget11(static_cast<ID3D11RenderTargetView *>(nullptr), nullptr,
nullptr, format, d3d11::ANGLE_FORMAT_NONE, width, height,
1, supportedSamples);
nullptr, nullptr, format, d3d11::ANGLE_FORMAT_NONE,
width, height, 1, supportedSamples);
}
return gl::Error(GL_NO_ERROR);
......@@ -3863,7 +3895,12 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
readTexture = readRenderTarget11->getTexture();
readTexture->AddRef();
readSubresource = readRenderTarget11->getSubresourceIndex();
readSRV = readRenderTarget11->getShaderResourceView();
readSRV = readRenderTarget11->getBlitShaderResourceView();
if (readSRV == nullptr)
{
ASSERT(depthBlit || stencilBlit);
readSRV = readRenderTarget11->getShaderResourceView();
}
readSRV->AddRef();
}
......
......@@ -15,6 +15,7 @@
#include "libANGLE/renderer/d3d/TextureStorage.h"
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include <array>
#include <map>
namespace gl
......@@ -91,7 +92,7 @@ class TextureStorage11 : public TextureStorage
virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture) = 0;
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0;
gl::Error getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV);
gl::Error getSRVLevel(int mipLevel, bool blitSRV, ID3D11ShaderResourceView **outSRV);
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
ID3D11ShaderResourceView **outSRV) const = 0;
......@@ -144,7 +145,8 @@ class TextureStorage11 : public TextureStorage
typedef std::map<SRVKey, ID3D11ShaderResourceView *> SRVCache;
SRVCache mSrvCache;
ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
std::array<ID3D11ShaderResourceView *, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> mLevelSRVs;
std::array<ID3D11ShaderResourceView *, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> mLevelBlitSRVs;
};
class TextureStorage11_2D : public TextureStorage11
......@@ -277,6 +279,10 @@ class TextureStorage11_Cube : public TextureStorage11
private:
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
ID3D11ShaderResourceView **outSRV) const;
gl::Error createRenderTargetSRV(ID3D11Resource *texture,
const gl::ImageIndex &index,
DXGI_FORMAT resourceFormat,
ID3D11ShaderResourceView **srv) const;
static const size_t CUBE_FACE_COUNT = 6;
......@@ -354,6 +360,10 @@ class TextureStorage11_2DArray : public TextureStorage11
private:
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
ID3D11ShaderResourceView **outSRV) const;
gl::Error createRenderTargetSRV(ID3D11Resource *texture,
const gl::ImageIndex &index,
DXGI_FORMAT resourceFormat,
ID3D11ShaderResourceView **srv) const;
typedef std::pair<int, int> LevelLayerKey;
typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap;
......
......@@ -144,6 +144,7 @@ ANGLEFormatSet::ANGLEFormatSet()
srvFormat(DXGI_FORMAT_UNKNOWN),
rtvFormat(DXGI_FORMAT_UNKNOWN),
dsvFormat(DXGI_FORMAT_UNKNOWN),
blitSRVFormat(DXGI_FORMAT_UNKNOWN),
swizzleFormat(ANGLE_FORMAT_NONE),
mipGenerationFunction(nullptr),
colorReadFunction(nullptr)
......@@ -174,6 +175,7 @@ ANGLEFormatSet::ANGLEFormatSet(ANGLEFormat format,
DXGI_FORMAT srvFormat,
DXGI_FORMAT rtvFormat,
DXGI_FORMAT dsvFormat,
DXGI_FORMAT blitSRVFormat,
ANGLEFormat swizzleFormat,
MipGenerationFunction mipGenerationFunction,
ColorReadFunction colorReadFunction)
......@@ -183,6 +185,7 @@ ANGLEFormatSet::ANGLEFormatSet(ANGLEFormat format,
srvFormat(srvFormat),
rtvFormat(rtvFormat),
dsvFormat(dsvFormat),
blitSRVFormat(blitSRVFormat),
swizzleFormat(swizzleFormat),
mipGenerationFunction(mipGenerationFunction),
colorReadFunction(colorReadFunction)
......@@ -441,6 +444,14 @@ def get_color_read_function(angle_format):
}
return 'ReadColor<' + channel_struct + ', '+ component_type_map[angle_format['componentType']] + '>'
def get_blit_srv_format(angle_format):
if 'channels' not in angle_format:
return 'DXGI_FORMAT_UNKNOWN'
if 'r' in angle_format['channels'] and angle_format['componentType'] in ['int', 'uint']:
return angle_format['rtvFormat']
return angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
def parse_json_into_switch_angle_format_string(json_data):
table_data = ''
for angle_format_item in sorted(json_data.iteritems()):
......@@ -451,6 +462,7 @@ def parse_json_into_switch_angle_format_string(json_data):
srv_format = angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
rtv_format = angle_format["rtvFormat"] if "rtvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
dsv_format = angle_format["dsvFormat"] if "dsvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
blit_srv_format = get_blit_srv_format(angle_format)
swizzle_format = get_swizzle_format_id(angle_format_item[0], angle_format)
mip_generation_function = get_mip_generation_function(angle_format)
color_read_function = get_color_read_function(angle_format)
......@@ -461,6 +473,7 @@ def parse_json_into_switch_angle_format_string(json_data):
table_data += ' ' + srv_format + ',\n'
table_data += ' ' + rtv_format + ',\n'
table_data += ' ' + dsv_format + ',\n'
table_data += ' ' + blit_srv_format + ',\n'
table_data += ' ' + swizzle_format + ',\n'
table_data += ' ' + mip_generation_function + ',\n'
table_data += ' ' + color_read_function + ');\n'
......
......@@ -46,6 +46,7 @@ struct ANGLEFormatSet
DXGI_FORMAT srvFormat,
DXGI_FORMAT rtvFormat,
DXGI_FORMAT dsvFormat,
DXGI_FORMAT blitSRVFormat,
ANGLEFormat swizzleFormat,
MipGenerationFunction mipGenerationFunction,
ColorReadFunction colorReadFunction);
......@@ -63,6 +64,8 @@ struct ANGLEFormatSet
DXGI_FORMAT rtvFormat;
DXGI_FORMAT dsvFormat;
DXGI_FORMAT blitSRVFormat;
ANGLEFormat swizzleFormat;
MipGenerationFunction mipGenerationFunction;
......
......@@ -85,12 +85,10 @@ class SwizzleTest : public ANGLETest
);
mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
if (mProgram == 0)
{
FAIL() << "shader compilation failed.";
}
ASSERT_NE(0u, mProgram);
mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
ASSERT_NE(-1, mTextureUniformLocation);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
ASSERT_GL_NO_ERROR();
......@@ -202,6 +200,54 @@ class SwizzleTest : public ANGLETest
std::vector<swizzlePermutation> mPermutations;
};
class SwizzleIntegerTest : public SwizzleTest
{
protected:
void SetUp() override
{
ANGLETest::SetUp();
const std::string vertexShaderSource =
"#version 300 es\n"
"precision highp float;\n"
"in vec4 position;\n"
"out vec2 texcoord;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = position;\n"
" texcoord = (position.xy * 0.5) + 0.5;\n"
"}\n";
const std::string fragmentShaderSource =
"#version 300 es\n"
"precision highp float;\n"
"precision highp usampler2D;\n"
"uniform usampler2D tex;\n"
"in vec2 texcoord;\n"
"out vec4 my_FragColor;\n"
"\n"
"void main()\n"
"{\n"
" uvec4 s = texture(tex, texcoord);\n"
" if (s[0] == 1u) s[0] = 255u;\n"
" if (s[1] == 1u) s[1] = 255u;\n"
" if (s[2] == 1u) s[2] = 255u;\n"
" if (s[3] == 1u) s[3] = 255u;\n"
" my_FragColor = vec4(s) / 255.0;\n"
"}\n";
mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
ASSERT_NE(0u, mProgram);
mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
ASSERT_NE(-1, mTextureUniformLocation);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
ASSERT_GL_NO_ERROR();
}
};
TEST_P(SwizzleTest, RGBA8_2D)
{
GLubyte data[] = { 1, 64, 128, 200 };
......@@ -346,7 +392,19 @@ TEST_P(SwizzleTest, CompressedDXT_2D)
runTest2D();
}
TEST_P(SwizzleIntegerTest, RGB8UI_2D)
{
GLubyte data[] = {77, 66, 55};
init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
runTest2D();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGL(3, 3), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest,
ES3_D3D11(),
ES3_OPENGL(),
ES3_OPENGL(3, 3),
ES3_OPENGLES());
} // namespace
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