зеркало из https://github.com/AvaloniaUI/angle.git
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:
Родитель
57ff6f95f1
Коммит
a49f60fee7
|
@ -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
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче