D3D11: Resolve multisampled EGL surfaces at eglSwapBuffers

Support for multisampled EGL surfaces was added in
151d5de (2017-04-13, "Enable MSAA for texture client buffers")
but the resolve step was missing because it was not needed for
EGL_ANGLE_d3d_texture_client_buffer. However, when using MSAA
with a regular EGL surface then resolving is required to get
an antialiased image.
Please note that the new test case CreateSurfaceWithMSAA does
actually not test the newly added resolve step because the
resolve is performed by the glReadPixels() call there.
So it is rather a general test if MSAA works for EGL surfaces.

TEST=angle_end2end_tests.EGLSurfaceTest.CreateSurfaceWithMSAA

Change-Id: Ieafd6877fa510d5e16c0d9c6872c31fa73efa86c
Reviewed-on: https://chromium-review.googlesource.com/1181138
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Till Rathmann 2018-08-20 16:03:06 +02:00 коммит произвёл Commit Bot
Родитель 57ff6f95f1
Коммит a49f60fee7
7 изменённых файлов: 224 добавлений и 13 удалений

Просмотреть файл

@ -23,6 +23,7 @@
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h"
#ifdef ANGLE_ENABLE_KEYEDMUTEX
#define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
@ -87,7 +88,7 @@ SwapChain11::SwapChain11(Renderer11 *renderer,
mPassThroughSampler(),
mPassThroughIL(),
mPassThroughVS(),
mPassThroughPS(),
mPassThroughOrResolvePS(),
mPassThroughRS(),
mColorRenderTarget(this, renderer, false),
mDepthStencilRenderTarget(this, renderer, true),
@ -129,7 +130,7 @@ void SwapChain11::release()
mPassThroughSampler.reset();
mPassThroughIL.reset();
mPassThroughVS.reset();
mPassThroughPS.reset();
mPassThroughOrResolvePS.reset();
mPassThroughRS.reset();
if (!mAppCreatedShareHandle)
@ -604,9 +605,9 @@ EGLint SwapChain11::reset(DisplayD3D *displayD3D,
if (mNativeWindow->getNativeWindow())
{
HRESULT hr = mNativeWindow->createSwapChain(device, mRenderer->getDxgiFactory(),
getSwapChainNativeFormat(), backbufferWidth,
backbufferHeight, getD3DSamples(), &mSwapChain);
HRESULT hr = mNativeWindow->createSwapChain(
device, mRenderer->getDxgiFactory(), getSwapChainNativeFormat(), backbufferWidth,
backbufferHeight, mNeedsOffscreenTexture ? 1 : getD3DSamples(), &mSwapChain);
if (FAILED(hr))
{
@ -668,7 +669,7 @@ angle::Result SwapChain11::initPassThroughResources(DisplayD3D *displayD3D)
// Make sure our resources are all not allocated, when we create
ASSERT(!mQuadVB.valid() && !mPassThroughSampler.valid());
ASSERT(!mPassThroughIL.valid() && !mPassThroughVS.valid() && !mPassThroughPS.valid());
ASSERT(!mPassThroughIL.valid() && !mPassThroughVS.valid() && !mPassThroughOrResolvePS.valid());
D3D11_BUFFER_DESC vbDesc;
vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
@ -718,15 +719,26 @@ angle::Result SwapChain11::initPassThroughResources(DisplayD3D *displayD3D)
if (mEGLSamples <= 1)
{
ShaderData pixelShaderData(g_PS_PassthroughRGBA2D);
ANGLE_TRY(mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughPS));
ANGLE_TRY(
mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughOrResolvePS));
}
else
{
ShaderData pixelShaderData(g_PS_PassthroughRGBA2DMS);
ANGLE_TRY(mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughPS));
if (mNativeWindow->getNativeWindow() && mNeedsOffscreenTexture)
{
ShaderData pixelShaderData(g_PS_ResolveColor2D);
ANGLE_TRY(
mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughOrResolvePS));
}
else
{
ShaderData pixelShaderData(g_PS_PassthroughRGBA2DMS);
ANGLE_TRY(
mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughOrResolvePS));
}
}
mPassThroughPS.setDebugName("Swap chain pass through pixel shader");
mPassThroughOrResolvePS.setDebugName("Swap chain pass through pixel shader");
// Use the default rasterizer state but without culling
D3D11_RASTERIZER_DESC rasterizerDesc;
@ -845,7 +857,7 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(DisplayD3D *displayD3D,
// Apply shaders
stateManager->setInputLayout(&mPassThroughIL);
stateManager->setPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
stateManager->setDrawShaders(&mPassThroughVS, nullptr, &mPassThroughPS);
stateManager->setDrawShaders(&mPassThroughVS, nullptr, &mPassThroughOrResolvePS);
// Apply render targets. Use the proxy context in display.
stateManager->setRenderTarget(mBackBufferRTView.get(), nullptr);

Просмотреть файл

@ -119,7 +119,7 @@ class SwapChain11 final : public SwapChainD3D
d3d11::SamplerState mPassThroughSampler;
d3d11::InputLayout mPassThroughIL;
d3d11::VertexShader mPassThroughVS;
d3d11::PixelShader mPassThroughPS;
d3d11::PixelShader mPassThroughOrResolvePS;
d3d11::RasterizerState mPassThroughRS;
SurfaceRenderTarget11 mColorRenderTarget;

Просмотреть файл

@ -0,0 +1,23 @@
Texture2DMS<float4> TextureF_MS : register(t0);
// VS_ResolveColor2D: not needed, we reuse VS_Passthrough2D
float4 PS_ResolveColor2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCORD0) : SV_TARGET0
{
uint width, height, samples;
TextureF_MS.GetDimensions(width, height, samples);
uint2 coord = uint2(inTexCoord.x * float(width), inTexCoord.y * float(height));
float4 color = float4(0.0, 0.0, 0.0, 0.0);
for (uint s = 0; s < samples; s++)
{
color += TextureF_MS.Load(coord, s).rgba;
}
return color / float(samples);
// Potential performance improvement: We could remove the TextureF_MS.GetDimensions() call
// and pass width, height, and invSamples via constants to the shader. This would allow us
// to calculate the final texture coordinates in the vertex shader already and instead of
// dividing by samples we could multiply by invSamples at the end.
// But maybe graphics drivers even do these optimizations automatically after the texture
// metrics are known at rendering time?
}

Просмотреть файл

@ -0,0 +1,103 @@
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
//
//
// Resource Bindings:
//
// Name Type Format Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// TextureF_MS texture float4 2dMS 0 1
//
//
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION 0 xyzw 0 POS float
// TEXCORD 0 xy 1 NONE float xy
//
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_TARGET 0 xyzw 0 TARGET float xyzw
//
ps_4_1
dcl_globalFlags refactoringAllowed
dcl_resource_texture2dms(0) (float,float,float,float) t0
dcl_input_ps linear v1.xy
dcl_output o0.xyzw
dcl_temps 4
resinfo_uint r0.xy, l(0), t0.xyzw
sampleinfo_uint r0.z, t0.x
utof r0.xy, r0.xyxx
mul r0.xy, r0.xyxx, v1.xyxx
ftou r1.xy, r0.xyxx
mov r1.zw, l(0,0,0,0)
mov r2.xyzw, l(0,0,0,0)
mov r0.x, l(0)
loop
uge r0.y, r0.x, r0.z
breakc_nz r0.y
ldms r3.xyzw, r1.xyzw, t0.xyzw, r0.x
add r2.xyzw, r2.xyzw, r3.xyzw
iadd r0.x, r0.x, l(1)
endloop
sampleinfo r0.x, t0.x
div o0.xyzw, r2.xyzw, r0.xxxx
ret
// Approximately 18 instruction slots used
#endif
const BYTE g_PS_ResolveColor2D[] = {
68, 88, 66, 67, 42, 5, 72, 36, 83, 93, 30, 221, 92, 105, 25, 91, 19, 46, 255,
126, 1, 0, 0, 0, 136, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 184, 0,
0, 0, 12, 1, 0, 0, 64, 1, 0, 0, 12, 3, 0, 0, 82, 68, 69, 70, 124,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
1, 4, 255, 255, 0, 1, 0, 0, 72, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 77, 83, 0, 77,
105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83,
104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46,
57, 54, 48, 48, 46, 49, 54, 51, 56, 52, 0, 171, 171, 73, 83, 71, 78, 76, 0,
0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0,
0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 82,
68, 0, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68,
82, 196, 1, 0, 0, 65, 0, 0, 0, 113, 0, 0, 0, 106, 8, 0, 1, 88, 32,
0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50,
16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0,
104, 0, 0, 2, 4, 0, 0, 0, 61, 16, 0, 7, 50, 0, 16, 0, 0, 0, 0,
0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 111, 8,
0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 112, 16, 0, 0, 0, 0, 0, 86,
0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0,
56, 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0,
0, 70, 16, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 1, 0,
0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1,
0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 54, 0, 0, 8, 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48,
0, 0, 1, 80, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0,
0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16,
0, 0, 0, 0, 0, 46, 0, 0, 9, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14,
16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0,
0, 0, 0, 0, 0, 0, 7, 242, 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0,
2, 0, 0, 0, 70, 14, 16, 0, 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16,
0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0,
0, 0, 22, 0, 0, 1, 111, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10,
112, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0,
70, 14, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0,
1, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 4, 0, 0, 0, 0, 0,
0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

Просмотреть файл

@ -35,6 +35,8 @@ call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D_4444 ps_4_0_level_9_3
call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D_565 ps_4_0_level_9_3 compiled\passthroughrgb2d_565_11ps.h %debug%
call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D_5551 ps_4_0_level_9_3 compiled\passthroughrgba2d_5551_11ps.h %debug%
call:BuildShader ResolveColor.hlsl PS_ResolveColor2D ps_4_1 compiled\resolvecolor2dps.h %debug%
call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_RGBA ps_4_0 compiled\multiplyalpha_ftof_pm_rgba_ps.h %debug%
call:BuildShader MultiplyAlpha.hlsl PS_FtoF_UM_RGBA ps_4_0 compiled\multiplyalpha_ftof_um_rgba_ps.h %debug%
call:BuildShader MultiplyAlpha.hlsl PS_FtoF_PM_RGB ps_4_0 compiled\multiplyalpha_ftof_pm_rgb_ps.h %debug%

Просмотреть файл

@ -533,6 +533,7 @@ libangle_d3d11_sources = [
"src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h",
"src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h",
"src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h",
"src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h",
"src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h",
"src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h",
"src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h",

Просмотреть файл

@ -659,5 +659,75 @@ TEST_F(EGLSurfaceTest, CreateDirectCompositionSurface)
glDeleteProgram(program);
}
#endif
TEST_F(EGLSurfaceTest, CreateSurfaceWithMSAA)
{
if (!ANGLETest::eglDisplayExtensionEnabled(EGL_NO_DISPLAY, "EGL_ANGLE_platform_angle_d3d"))
{
std::cout << "D3D Platform not supported in ANGLE" << std::endl;
return;
}
// clang-format off
const EGLint configAttributes[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 0,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_SAMPLE_BUFFERS, 1,
EGL_SAMPLES, 4,
EGL_NONE
};
// clang-format on
initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
EGLConfig config;
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
{
std::cout << "EGLConfig for 4xMSAA is not supported, skipping test" << std::endl;
return;
}
initializeSurface(config);
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
ASSERT_EGL_SUCCESS();
GLuint program = createProgram();
ASSERT_NE(0u, program);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
GLint positionLocation = glGetAttribLocation(program, "position");
glUseProgram(program);
const GLfloat halfPixelOffset = 0.5f * 2.0f / mOSWindow->getWidth();
// clang-format off
const GLfloat vertices[] =
{
-1.0f + halfPixelOffset, 1.0f, 0.5f,
-1.0f + halfPixelOffset, -1.0f, 0.5f,
1.0f, -1.0f, 0.5f
};
// clang-format on
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(positionLocation);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
EXPECT_PIXEL_NEAR(0, 0, 127, 0, 0, 255, 10);
EXPECT_GL_NO_ERROR();
glDeleteProgram(program);
}
#endif // ANGLE_ENABLE_D3D11
}