Commit 151d5de6 by Bryan Bernhart (Intel Americas Inc) Committed by Commit Bot

Enable MSAA for texture client buffers

Enhancement to the EGL_ANGLE_d3d_texture_client_buffer extension to allow use of a shared D3D texture that can be multi-sampled. BUG=angleproject:1917 Change-Id: Iaf59bbd575a5dfb29345f55b549bc4017bf2d7d0 Reviewed-on: https://chromium-review.googlesource.com/446907Reviewed-by: 's avatarBryan Bernhart <bryan.bernhart@intel.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 331f6dbd
...@@ -101,6 +101,11 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) ...@@ -101,6 +101,11 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
Issues Issues
1. What renderers allow the use of a multi-sampled texture?
PROPOSED: Mutli-sampled texture support is currently limited to D3D11. Additionally,
the client is responsible for resolving the texture.
Revision History Revision History
Version 1, 2016/10/05 - first draft. Version 1, 2016/10/05 - first draft.
...@@ -293,8 +293,8 @@ egl::Error DisplayD3D::validateClientBuffer(const egl::Config *configuration, ...@@ -293,8 +293,8 @@ egl::Error DisplayD3D::validateClientBuffer(const egl::Config *configuration,
attribs); attribs);
case EGL_D3D_TEXTURE_ANGLE: case EGL_D3D_TEXTURE_ANGLE:
return mRenderer->getD3DTextureInfo(static_cast<IUnknown *>(clientBuffer), nullptr, return mRenderer->getD3DTextureInfo(
nullptr, nullptr); configuration, static_cast<IUnknown *>(clientBuffer), nullptr, nullptr, nullptr);
default: default:
return DisplayImpl::validateClientBuffer(configuration, buftype, clientBuffer, attribs); return DisplayImpl::validateClientBuffer(configuration, buftype, clientBuffer, attribs);
......
...@@ -135,8 +135,10 @@ class RendererD3D : public BufferFactoryD3D ...@@ -135,8 +135,10 @@ class RendererD3D : public BufferFactoryD3D
IUnknown *d3dTexture, IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) = 0; EGLint orientation,
virtual egl::Error getD3DTextureInfo(IUnknown *d3dTexture, EGLint samples) = 0;
virtual egl::Error getD3DTextureInfo(const egl::Config *configuration,
IUnknown *d3dTexture,
EGLint *width, EGLint *width,
EGLint *height, EGLint *height,
GLenum *fboFormat) const = 0; GLenum *fboFormat) const = 0;
......
...@@ -60,7 +60,8 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state, ...@@ -60,7 +60,8 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
mD3DTexture = static_cast<IUnknown *>(clientBuffer); mD3DTexture = static_cast<IUnknown *>(clientBuffer);
ASSERT(mD3DTexture != nullptr); ASSERT(mD3DTexture != nullptr);
mD3DTexture->AddRef(); mD3DTexture->AddRef();
mRenderer->getD3DTextureInfo(mD3DTexture, &mWidth, &mHeight, &mRenderTargetFormat); mRenderer->getD3DTextureInfo(state.config, mD3DTexture, &mWidth, &mHeight,
&mRenderTargetFormat);
break; break;
default: default:
...@@ -146,8 +147,9 @@ egl::Error SurfaceD3D::resetSwapChain() ...@@ -146,8 +147,9 @@ egl::Error SurfaceD3D::resetSwapChain()
height = mHeight; height = mHeight;
} }
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture, mSwapChain =
mRenderTargetFormat, mDepthStencilFormat, mOrientation); mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture, mRenderTargetFormat,
mDepthStencilFormat, mOrientation, mState.config->samples);
if (!mSwapChain) if (!mSwapChain)
{ {
return egl::Error(EGL_BAD_ALLOC); return egl::Error(EGL_BAD_ALLOC);
......
...@@ -29,6 +29,7 @@ class NativeWindow11 : public NativeWindowD3D ...@@ -29,6 +29,7 @@ class NativeWindow11 : public NativeWindowD3D
DXGI_FORMAT format, DXGI_FORMAT format,
UINT width, UINT width,
UINT height, UINT height,
UINT samples,
IDXGISwapChain **swapChain) = 0; IDXGISwapChain **swapChain) = 0;
virtual void commitChange() = 0; virtual void commitChange() = 0;
}; };
......
...@@ -405,8 +405,7 @@ GLenum SurfaceRenderTarget11::getInternalFormat() const ...@@ -405,8 +405,7 @@ GLenum SurfaceRenderTarget11::getInternalFormat() const
GLsizei SurfaceRenderTarget11::getSamples() const GLsizei SurfaceRenderTarget11::getSamples() const
{ {
// Our EGL surfaces do not support multisampling. return mSwapChain->getSamples();
return 0;
} }
ID3D11Resource *SurfaceRenderTarget11::getTexture() const ID3D11Resource *SurfaceRenderTarget11::getTexture() const
......
...@@ -126,8 +126,10 @@ class Renderer11 : public RendererD3D ...@@ -126,8 +126,10 @@ class Renderer11 : public RendererD3D
IUnknown *d3dTexture, IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) override; EGLint orientation,
egl::Error getD3DTextureInfo(IUnknown *d3dTexture, EGLint samples) override;
egl::Error getD3DTextureInfo(const egl::Config *configuration,
IUnknown *d3dTexture,
EGLint *width, EGLint *width,
EGLint *height, EGLint *height,
GLenum *fboFormat) const override; GLenum *fboFormat) const override;
...@@ -488,6 +490,10 @@ class Renderer11 : public RendererD3D ...@@ -488,6 +490,10 @@ class Renderer11 : public RendererD3D
const gl::Offset &destOffset, const gl::Offset &destOffset,
RenderTargetD3D *destRenderTarget); RenderTargetD3D *destRenderTarget);
gl::SupportedSampleSet generateSampleSetFromCaps(
const gl::TextureCaps &colorBufferFormatCaps,
const gl::TextureCaps &depthStencilBufferFormatCaps) const;
HMODULE mD3d11Module; HMODULE mD3d11Module;
HMODULE mDxgiModule; HMODULE mDxgiModule;
HMODULE mDCompModule; HMODULE mDCompModule;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
// Precompiled shaders // Precompiled shaders
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h" #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/passthroughrgba2d11ps.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h"
#ifdef ANGLE_ENABLE_KEYEDMUTEX #ifdef ANGLE_ENABLE_KEYEDMUTEX
#define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX #define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
...@@ -54,7 +55,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, ...@@ -54,7 +55,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer,
IUnknown *d3dTexture, IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) EGLint orientation,
EGLint samples)
: SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat), : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat),
mRenderer(renderer), mRenderer(renderer),
mWidth(-1), mWidth(-1),
...@@ -85,7 +87,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, ...@@ -85,7 +87,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer,
mPassThroughPS(nullptr), mPassThroughPS(nullptr),
mPassThroughRS(nullptr), mPassThroughRS(nullptr),
mColorRenderTarget(this, renderer, false), mColorRenderTarget(this, renderer, false),
mDepthStencilRenderTarget(this, renderer, true) mDepthStencilRenderTarget(this, renderer, true),
mEGLSamples(samples)
{ {
// Sanity check that if present path fast is active then we're using the default orientation // Sanity check that if present path fast is active then we're using the default orientation
ASSERT(!mRenderer->presentPathFastEnabled() || orientation == 0); ASSERT(!mRenderer->presentPathFastEnabled() || orientation == 0);
...@@ -230,7 +233,7 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe ...@@ -230,7 +233,7 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe
offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.MipLevels = 1;
offscreenTextureDesc.ArraySize = 1; offscreenTextureDesc.ArraySize = 1;
offscreenTextureDesc.SampleDesc.Count = 1; offscreenTextureDesc.SampleDesc.Count = getD3DSamples();
offscreenTextureDesc.SampleDesc.Quality = 0; offscreenTextureDesc.SampleDesc.Quality = 0;
offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT; offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
...@@ -286,7 +289,8 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe ...@@ -286,7 +289,8 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe
D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat;
offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; offscreenRTVDesc.ViewDimension =
(mEGLSamples <= 1) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
offscreenRTVDesc.Texture2D.MipSlice = 0; offscreenRTVDesc.Texture2D.MipSlice = 0;
HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, &offscreenRTVDesc, &mOffscreenRTView); HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, &offscreenRTVDesc, &mOffscreenRTView);
...@@ -295,7 +299,8 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe ...@@ -295,7 +299,8 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe
D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc;
offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat;
offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; offscreenSRVDesc.ViewDimension =
(mEGLSamples <= 1) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
offscreenSRVDesc.Texture2D.MostDetailedMip = 0; offscreenSRVDesc.Texture2D.MostDetailedMip = 0;
offscreenSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1); offscreenSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1);
...@@ -348,7 +353,7 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe ...@@ -348,7 +353,7 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe
depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.MipLevels = 1;
depthStencilTextureDesc.ArraySize = 1; depthStencilTextureDesc.ArraySize = 1;
depthStencilTextureDesc.SampleDesc.Count = 1; depthStencilTextureDesc.SampleDesc.Count = getD3DSamples();
depthStencilTextureDesc.SampleDesc.Quality = 0; depthStencilTextureDesc.SampleDesc.Quality = 0;
depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
...@@ -383,7 +388,8 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe ...@@ -383,7 +388,8 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc;
depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat;
depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilDesc.ViewDimension =
(mEGLSamples <= 1) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
depthStencilDesc.Flags = 0; depthStencilDesc.Flags = 0;
depthStencilDesc.Texture2D.MipSlice = 0; depthStencilDesc.Texture2D.MipSlice = 0;
...@@ -395,7 +401,9 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe ...@@ -395,7 +401,9 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe
{ {
D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc;
depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat;
depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; depthStencilSRVDesc.ViewDimension = (mEGLSamples <= 1)
? D3D11_SRV_DIMENSION_TEXTURE2D
: D3D11_SRV_DIMENSION_TEXTURE2DMS;
depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; depthStencilSRVDesc.Texture2D.MostDetailedMip = 0;
depthStencilSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1); depthStencilSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1);
...@@ -557,9 +565,9 @@ EGLint SwapChain11::reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLin ...@@ -557,9 +565,9 @@ EGLint SwapChain11::reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLin
if (mNativeWindow->getNativeWindow()) if (mNativeWindow->getNativeWindow())
{ {
HRESULT result = mNativeWindow->createSwapChain(device, mRenderer->getDxgiFactory(), HRESULT result = mNativeWindow->createSwapChain(
getSwapChainNativeFormat(), backbufferWidth, device, mRenderer->getDxgiFactory(), getSwapChainNativeFormat(), backbufferWidth,
backbufferHeight, &mSwapChain); backbufferHeight, getD3DSamples(), &mSwapChain);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -661,7 +669,17 @@ void SwapChain11::initPassThroughResources() ...@@ -661,7 +669,17 @@ void SwapChain11::initPassThroughResources()
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader"); d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader");
result = device->CreatePixelShader(g_PS_PassthroughRGBA2D, sizeof(g_PS_PassthroughRGBA2D), NULL, &mPassThroughPS); if (mEGLSamples <= 1)
{
result = device->CreatePixelShader(g_PS_PassthroughRGBA2D, sizeof(g_PS_PassthroughRGBA2D),
nullptr, &mPassThroughPS);
}
else
{
result = device->CreatePixelShader(
g_PS_PassthroughRGBA2DMS, sizeof(g_PS_PassthroughRGBA2DMS), nullptr, &mPassThroughPS);
}
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader"); d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader");
...@@ -822,7 +840,8 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) ...@@ -822,7 +840,8 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height)
HRESULT result = S_OK; HRESULT result = S_OK;
// Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available. // Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available.
if (mSwapChain1 != nullptr) // Dirty rect present is not supported with a multisampled swapchain.
if (mSwapChain1 != nullptr && mEGLSamples <= 1)
{ {
if (mFirstSwap) if (mFirstSwap)
{ {
...@@ -947,4 +966,9 @@ egl::Error SwapChain11::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLu ...@@ -947,4 +966,9 @@ egl::Error SwapChain11::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLu
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
} }
UINT SwapChain11::getD3DSamples() const
{
return (mEGLSamples == 0) ? 1 : mEGLSamples;
}
} // namespace rx } // namespace rx
...@@ -27,7 +27,8 @@ class SwapChain11 final : public SwapChainD3D ...@@ -27,7 +27,8 @@ class SwapChain11 final : public SwapChainD3D
IUnknown *d3dTexture, IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation); EGLint orientation,
EGLint samples);
virtual ~SwapChain11(); virtual ~SwapChain11();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
...@@ -49,6 +50,7 @@ class SwapChain11 final : public SwapChainD3D ...@@ -49,6 +50,7 @@ class SwapChain11 final : public SwapChainD3D
EGLint getWidth() const { return mWidth; } EGLint getWidth() const { return mWidth; }
EGLint getHeight() const { return mHeight; } EGLint getHeight() const { return mHeight; }
void *getKeyedMutex() override { return mKeyedMutex; } void *getKeyedMutex() override { return mKeyedMutex; }
EGLint getSamples() const { return mEGLSamples; }
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
...@@ -66,6 +68,7 @@ class SwapChain11 final : public SwapChainD3D ...@@ -66,6 +68,7 @@ class SwapChain11 final : public SwapChainD3D
EGLint copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height); EGLint copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height);
EGLint present(EGLint x, EGLint y, EGLint width, EGLint height); EGLint present(EGLint x, EGLint y, EGLint width, EGLint height);
UINT getD3DSamples() const;
Renderer11 *mRenderer; Renderer11 *mRenderer;
EGLint mWidth; EGLint mWidth;
...@@ -105,6 +108,7 @@ class SwapChain11 final : public SwapChainD3D ...@@ -105,6 +108,7 @@ class SwapChain11 final : public SwapChainD3D
SurfaceRenderTarget11 mColorRenderTarget; SurfaceRenderTarget11 mColorRenderTarget;
SurfaceRenderTarget11 mDepthStencilRenderTarget; SurfaceRenderTarget11 mDepthStencilRenderTarget;
EGLint mEGLSamples;
LONGLONG mQPCFrequency; LONGLONG mQPCFrequency;
}; };
......
Texture2D<float4> TextureF : register(t0); Texture2D<float4> TextureF : register(t0);
Texture2DMS<float4> TextureF_MS: register(t0);
Texture2D<uint4> TextureUI : register(t0); Texture2D<uint4> TextureUI : register(t0);
Texture2D<int4> TextureI : register(t0); Texture2D<int4> TextureI : register(t0);
...@@ -21,6 +22,11 @@ float4 PS_PassthroughRGBA2D(in float4 inPosition : SV_POSITION, in float2 inTexC ...@@ -21,6 +22,11 @@ float4 PS_PassthroughRGBA2D(in float4 inPosition : SV_POSITION, in float2 inTexC
return TextureF.Sample(Sampler, inTexCoord).rgba; return TextureF.Sample(Sampler, inTexCoord).rgba;
} }
float4 PS_PassthroughRGBA2DMS(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCORD0, in uint inSampleIndex : SV_SAMPLEINDEX) : SV_TARGET0
{
return TextureF_MS.sample[inSampleIndex][inTexCoord].rgba;
}
float4 PS_PassthroughRGBAPremultiply2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 float4 PS_PassthroughRGBAPremultiply2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
{ {
float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; float4 color = TextureF.Sample(Sampler, inTexCoord).rgba;
......
#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
// SV_SAMPLEINDEX 0 x 2 SAMPLE uint x
//
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_TARGET 0 xyzw 0 TARGET float xyzw
//
// Pixel Shader runs at sample frequency
//
ps_4_1
dcl_globalFlags refactoringAllowed
dcl_resource_texture2dms(0) (float,float,float,float) t0
dcl_input_ps linear v1.xy
dcl_input_ps_sgv v2.x, sampleIndex
dcl_output o0.xyzw
dcl_temps 1
ftou r0.xy, v1.xyxx
mov r0.zw, l(0,0,0,0)
ldms o0.xyzw, r0.xyzw, t0.xyzw, v2.x
ret
// Approximately 4 instruction slots used
#endif
const BYTE g_PS_PassthroughRGBA2DMS[] = {
68, 88, 66, 67, 153, 49, 112, 211, 187, 16, 68, 138, 16, 138, 141, 230, 21, 218, 248,
134, 1, 0, 0, 0, 144, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 180, 0,
0, 0, 48, 1, 0, 0, 100, 1, 0, 0, 20, 2, 0, 0, 82, 68, 69, 70, 120,
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, 69, 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, 77, 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, 73, 83, 71, 78, 116, 0, 0, 0, 3, 0,
0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3,
0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 100, 0, 0,
0, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 1,
0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79,
82, 68, 0, 83, 86, 95, 83, 65, 77, 80, 76, 69, 73, 78, 68, 69, 88, 0, 171,
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, 168,
0, 0, 0, 65, 0, 0, 0, 42, 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, 99, 8, 0, 4, 18, 16, 16, 0, 2, 0, 0, 0, 10, 0,
0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0,
1, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0,
0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70,
126, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1,
83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 3, 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, 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, 1, 0, 0, 0, 0, 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};
...@@ -23,6 +23,7 @@ if "%1" == "release" ( ...@@ -23,6 +23,7 @@ if "%1" == "release" (
:: | Input file | Entry point | Type | Output file | Debug | :: | Input file | Entry point | Type | Output file | Debug |
call:BuildShader Passthrough2D11.hlsl VS_Passthrough2D vs_4_0_level_9_3 compiled\passthrough2d11vs.h %debug% call:BuildShader Passthrough2D11.hlsl VS_Passthrough2D vs_4_0_level_9_3 compiled\passthrough2d11vs.h %debug%
call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D ps_4_0_level_9_3 compiled\passthroughrgba2d11ps.h %debug% call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D ps_4_0_level_9_3 compiled\passthroughrgba2d11ps.h %debug%
call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DMS ps_4_1 compiled\passthroughrgba2dms11ps.h %debug%
call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D ps_4_0_level_9_3 compiled\passthroughrgb2d11ps.h %debug% call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D ps_4_0_level_9_3 compiled\passthroughrgb2d11ps.h %debug%
call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2D ps_4_0_level_9_3 compiled\passthroughrg2d11ps.h %debug% call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2D ps_4_0_level_9_3 compiled\passthroughrg2d11ps.h %debug%
call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2D ps_4_0_level_9_3 compiled\passthroughr2d11ps.h %debug% call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2D ps_4_0_level_9_3 compiled\passthroughr2d11ps.h %debug%
......
...@@ -56,6 +56,7 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device, ...@@ -56,6 +56,7 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device,
DXGI_FORMAT format, DXGI_FORMAT format,
UINT width, UINT width,
UINT height, UINT height,
UINT samples,
IDXGISwapChain **swapChain) IDXGISwapChain **swapChain)
{ {
if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 || if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 ||
...@@ -153,8 +154,8 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device, ...@@ -153,8 +154,8 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device,
swapChainDesc.Height = height; swapChainDesc.Height = height;
swapChainDesc.Format = format; swapChainDesc.Format = format;
swapChainDesc.Stereo = FALSE; swapChainDesc.Stereo = FALSE;
swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Count = samples;
swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = swapChainDesc.BufferUsage =
DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.BufferCount = 1; swapChainDesc.BufferCount = 1;
...@@ -187,7 +188,7 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device, ...@@ -187,7 +188,7 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device,
DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.Flags = 0; swapChainDesc.Flags = 0;
swapChainDesc.OutputWindow = getNativeWindow(); swapChainDesc.OutputWindow = getNativeWindow();
swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Count = samples;
swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Windowed = TRUE; swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
......
...@@ -33,6 +33,7 @@ class NativeWindow11Win32 : public NativeWindow11 ...@@ -33,6 +33,7 @@ class NativeWindow11Win32 : public NativeWindow11
DXGI_FORMAT format, DXGI_FORMAT format,
UINT width, UINT width,
UINT height, UINT height,
UINT samples,
IDXGISwapChain **swapChain) override; IDXGISwapChain **swapChain) override;
void commitChange() override; void commitChange() override;
......
...@@ -683,13 +683,15 @@ SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow, ...@@ -683,13 +683,15 @@ SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow,
IUnknown *d3dTexture, IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) EGLint orientation,
EGLint samples)
{ {
return new SwapChain9(this, GetAs<NativeWindow9>(nativeWindow), shareHandle, d3dTexture, return new SwapChain9(this, GetAs<NativeWindow9>(nativeWindow), shareHandle, d3dTexture,
backBufferFormat, depthBufferFormat, orientation); backBufferFormat, depthBufferFormat, orientation);
} }
egl::Error Renderer9::getD3DTextureInfo(IUnknown *d3dTexture, egl::Error Renderer9::getD3DTextureInfo(const egl::Config *config,
IUnknown *d3dTexture,
EGLint *width, EGLint *width,
EGLint *height, EGLint *height,
GLenum *fboFormat) const GLenum *fboFormat) const
......
...@@ -91,8 +91,10 @@ class Renderer9 : public RendererD3D ...@@ -91,8 +91,10 @@ class Renderer9 : public RendererD3D
IUnknown *d3dTexture, IUnknown *d3dTexture,
GLenum backBufferFormat, GLenum backBufferFormat,
GLenum depthBufferFormat, GLenum depthBufferFormat,
EGLint orientation) override; EGLint orientation,
egl::Error getD3DTextureInfo(IUnknown *d3dTexture, EGLint samples) override;
egl::Error getD3DTextureInfo(const egl::Config *configuration,
IUnknown *d3dTexture,
EGLint *width, EGLint *width,
EGLint *height, EGLint *height,
GLenum *fboFormat) const override; GLenum *fboFormat) const override;
......
...@@ -72,6 +72,14 @@ class EGLContextCompatibilityTest : public ANGLETest ...@@ -72,6 +72,14 @@ class EGLContextCompatibilityTest : public ANGLETest
}; };
protected: protected:
// Queries EGL config to determine if multisampled or not
bool isMultisampledConfig(EGLConfig config)
{
EGLint samples = 0;
eglGetConfigAttrib(mDisplay, config, EGL_SAMPLES, &samples);
return (samples > 1);
}
bool areConfigsCompatible(EGLConfig c1, EGLConfig c2, EGLint surfaceBit) bool areConfigsCompatible(EGLConfig c1, EGLConfig c2, EGLint surfaceBit)
{ {
EGLint colorBufferType1, colorBufferType2; EGLint colorBufferType1, colorBufferType2;
...@@ -235,6 +243,12 @@ TEST_P(EGLContextCompatibilityTest, WindowSameConfig) ...@@ -235,6 +243,12 @@ TEST_P(EGLContextCompatibilityTest, WindowSameConfig)
if ((surfaceType & EGL_WINDOW_BIT) != 0) if ((surfaceType & EGL_WINDOW_BIT) != 0)
{ {
// Disabling multisampled configurations due to test instability with various graphics
// cards
if (isMultisampledConfig(config))
{
continue;
}
testWindowCompatibility(config, config, true); testWindowCompatibility(config, config, true);
} }
} }
...@@ -254,6 +268,12 @@ TEST_P(EGLContextCompatibilityTest, PbufferSameConfig) ...@@ -254,6 +268,12 @@ TEST_P(EGLContextCompatibilityTest, PbufferSameConfig)
if ((surfaceType & EGL_PBUFFER_BIT) != 0) if ((surfaceType & EGL_PBUFFER_BIT) != 0)
{ {
// Disabling multisampled configurations due to test instability with various graphics
// cards
if (isMultisampledConfig(config))
{
continue;
}
testPbufferCompatibility(config, config, true); testPbufferCompatibility(config, config, true);
} }
} }
...@@ -266,6 +286,12 @@ TEST_P(EGLContextCompatibilityTest, WindowDifferentConfig) ...@@ -266,6 +286,12 @@ TEST_P(EGLContextCompatibilityTest, WindowDifferentConfig)
for (size_t i = 0; i < mConfigs.size(); i++) for (size_t i = 0; i < mConfigs.size(); i++)
{ {
EGLConfig config1 = mConfigs[i]; EGLConfig config1 = mConfigs[i];
// Disabling multisampled configurations due to test instability with various graphics cards
if (isMultisampledConfig(config1))
{
continue;
}
EGLint surfaceType; EGLint surfaceType;
eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType); eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
ASSERT_EGL_SUCCESS(); ASSERT_EGL_SUCCESS();
...@@ -278,6 +304,12 @@ TEST_P(EGLContextCompatibilityTest, WindowDifferentConfig) ...@@ -278,6 +304,12 @@ TEST_P(EGLContextCompatibilityTest, WindowDifferentConfig)
for (size_t j = 0; j < mConfigs.size(); j++) for (size_t j = 0; j < mConfigs.size(); j++)
{ {
EGLConfig config2 = mConfigs[j]; EGLConfig config2 = mConfigs[j];
// Disabling multisampled configurations due to test instability with various graphics
// cards
if (isMultisampledConfig(config2))
{
continue;
}
testWindowCompatibility(config1, config2, testWindowCompatibility(config1, config2,
areConfigsCompatible(config1, config2, EGL_WINDOW_BIT)); areConfigsCompatible(config1, config2, EGL_WINDOW_BIT));
} }
...@@ -291,6 +323,12 @@ TEST_P(EGLContextCompatibilityTest, PbufferDifferentConfig) ...@@ -291,6 +323,12 @@ TEST_P(EGLContextCompatibilityTest, PbufferDifferentConfig)
for (size_t i = 0; i < mConfigs.size(); i++) for (size_t i = 0; i < mConfigs.size(); i++)
{ {
EGLConfig config1 = mConfigs[i]; EGLConfig config1 = mConfigs[i];
// Disabling multisampled configurations due to test instability with various graphics cards
if (isMultisampledConfig(config1))
{
continue;
}
EGLint surfaceType; EGLint surfaceType;
eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType); eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
ASSERT_EGL_SUCCESS(); ASSERT_EGL_SUCCESS();
...@@ -303,6 +341,12 @@ TEST_P(EGLContextCompatibilityTest, PbufferDifferentConfig) ...@@ -303,6 +341,12 @@ TEST_P(EGLContextCompatibilityTest, PbufferDifferentConfig)
for (size_t j = 0; j < mConfigs.size(); j++) for (size_t j = 0; j < mConfigs.size(); j++)
{ {
EGLConfig config2 = mConfigs[j]; EGLConfig config2 = mConfigs[j];
// Disabling multisampled configurations due to test instability with various graphics
// cards
if (isMultisampledConfig(config2))
{
continue;
}
testPbufferCompatibility(config1, config2, areConfigsCompatible(config1, config2, EGL_PBUFFER_BIT)); testPbufferCompatibility(config1, config2, areConfigsCompatible(config1, config2, EGL_PBUFFER_BIT));
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
// Tests of the EGL_ANGLE_d3d_texture_client_buffer extension // Tests of the EGL_ANGLE_d3d_texture_client_buffer extension
#include "test_utils/ANGLETest.h" #include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include <d3d11.h> #include <d3d11.h>
#include <windows.h> #include <windows.h>
...@@ -61,6 +62,16 @@ class D3DTextureTest : public ANGLETest ...@@ -61,6 +62,16 @@ class D3DTextureTest : public ANGLETest
gl_FragColor = texture2D(tex, texcoord); gl_FragColor = texture2D(tex, texcoord);
} }
); );
const std::string textureFSSourceNoSampling = SHADER_SOURCE
(
precision highp float;
void main()
{
gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}
);
// clang-format on // clang-format on
mTextureProgram = CompileProgram(vsSource, textureFSSource); mTextureProgram = CompileProgram(vsSource, textureFSSource);
...@@ -69,6 +80,9 @@ class D3DTextureTest : public ANGLETest ...@@ -69,6 +80,9 @@ class D3DTextureTest : public ANGLETest
mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
ASSERT_NE(-1, mTextureUniformLocation); ASSERT_NE(-1, mTextureUniformLocation);
mTextureProgramNoSampling = CompileProgram(vsSource, textureFSSourceNoSampling);
ASSERT_NE(0u, mTextureProgramNoSampling) << "shader compilation failed.";
mD3D11Module = LoadLibrary(TEXT("d3d11.dll")); mD3D11Module = LoadLibrary(TEXT("d3d11.dll"));
ASSERT_NE(nullptr, mD3D11Module); ASSERT_NE(nullptr, mD3D11Module);
...@@ -141,7 +155,9 @@ class D3DTextureTest : public ANGLETest ...@@ -141,7 +155,9 @@ class D3DTextureTest : public ANGLETest
EGLSurface createPBuffer(size_t width, EGLSurface createPBuffer(size_t width,
size_t height, size_t height,
EGLint eglTextureFormat, EGLint eglTextureFormat,
EGLint eglTextureTarget) EGLint eglTextureTarget,
UINT sampleCount,
UINT sampleQuality)
{ {
EGLWindow *window = getEGLWindow(); EGLWindow *window = getEGLWindow();
EGLDisplay display = window->getDisplay(); EGLDisplay display = window->getDisplay();
...@@ -158,6 +174,8 @@ class D3DTextureTest : public ANGLETest ...@@ -158,6 +174,8 @@ class D3DTextureTest : public ANGLETest
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, static_cast<UINT>(width), CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, static_cast<UINT>(width),
static_cast<UINT>(height), 1, 1, static_cast<UINT>(height), 1, 1,
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET); D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
desc.SampleDesc.Count = sampleCount;
desc.SampleDesc.Quality = sampleQuality;
EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture))); EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture)));
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE, EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,
...@@ -169,6 +187,10 @@ class D3DTextureTest : public ANGLETest ...@@ -169,6 +187,10 @@ class D3DTextureTest : public ANGLETest
} }
else if (mD3D9Device) else if (mD3D9Device)
{ {
// Multisampled textures are not supported on D3D9.
ASSERT(sampleCount <= 1);
ASSERT(sampleQuality == 0);
IDirect3DTexture9 *texture = nullptr; IDirect3DTexture9 *texture = nullptr;
EXPECT_TRUE(SUCCEEDED(mD3D9Device->CreateTexture( EXPECT_TRUE(SUCCEEDED(mD3D9Device->CreateTexture(
static_cast<UINT>(width), static_cast<UINT>(height), 1, D3DUSAGE_RENDERTARGET, static_cast<UINT>(width), static_cast<UINT>(height), 1, D3DUSAGE_RENDERTARGET,
...@@ -219,6 +241,7 @@ class D3DTextureTest : public ANGLETest ...@@ -219,6 +241,7 @@ class D3DTextureTest : public ANGLETest
} }
GLuint mTextureProgram; GLuint mTextureProgram;
GLuint mTextureProgramNoSampling;
GLint mTextureUniformLocation; GLint mTextureUniformLocation;
HMODULE mD3D11Module = nullptr; HMODULE mD3D11Module = nullptr;
...@@ -240,7 +263,8 @@ TEST_P(D3DTextureTest, Clear) ...@@ -240,7 +263,8 @@ TEST_P(D3DTextureTest, Clear)
const size_t bufferSize = 32; const size_t bufferSize = 32;
EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE); EGLSurface pbuffer =
createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 1, 0);
ASSERT_EGL_SUCCESS(); ASSERT_EGL_SUCCESS();
ASSERT_NE(pbuffer, EGL_NO_SURFACE); ASSERT_NE(pbuffer, EGL_NO_SURFACE);
...@@ -274,7 +298,8 @@ TEST_P(D3DTextureTest, DepthStencil) ...@@ -274,7 +298,8 @@ TEST_P(D3DTextureTest, DepthStencil)
const size_t bufferSize = 32; const size_t bufferSize = 32;
EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE); EGLSurface pbuffer =
createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 1, 0);
ASSERT_EGL_SUCCESS(); ASSERT_EGL_SUCCESS();
ASSERT_NE(pbuffer, EGL_NO_SURFACE); ASSERT_NE(pbuffer, EGL_NO_SURFACE);
...@@ -324,7 +349,8 @@ TEST_P(D3DTextureTest, BindTexImage) ...@@ -324,7 +349,8 @@ TEST_P(D3DTextureTest, BindTexImage)
const size_t bufferSize = 32; const size_t bufferSize = 32;
EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D); EGLSurface pbuffer =
createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0);
ASSERT_EGL_SUCCESS(); ASSERT_EGL_SUCCESS();
ASSERT_NE(pbuffer, EGL_NO_SURFACE); ASSERT_NE(pbuffer, EGL_NO_SURFACE);
...@@ -378,8 +404,141 @@ TEST_P(D3DTextureTest, BindTexImage) ...@@ -378,8 +404,141 @@ TEST_P(D3DTextureTest, BindTexImage)
eglDestroySurface(display, pbuffer); eglDestroySurface(display, pbuffer);
} }
// Verify that creating a pbuffer with a multisampled texture will fail on a non-multisampled
// window.
TEST_P(D3DTextureTest, CheckSampleMismatch)
{
if (!valid())
{
return;
}
// Multisampling is not supported on D3D9 or OpenGL.
if (IsD3D9() || IsOpenGL())
{
return;
}
constexpr size_t bufferSize = 32;
EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 2,
static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
EXPECT_EQ(pbuffer, nullptr);
}
class D3DTextureTestMS : public D3DTextureTest
{
protected:
D3DTextureTestMS() : D3DTextureTest()
{
setSamples(4);
setMultisampleEnabled(true);
}
};
// Test creating a pbuffer from a multisampled d3d surface and clearing it.
TEST_P(D3DTextureTestMS, Clear)
{
EGLWindow *window = getEGLWindow();
EGLDisplay display = window->getDisplay();
constexpr size_t bufferSize = 32;
constexpr UINT testpoint = bufferSize / 2;
EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
ASSERT_EGL_SUCCESS();
ASSERT_NE(pbuffer, EGL_NO_SURFACE);
// Apply the Pbuffer and clear it to magenta and verify
eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
ASSERT_EGL_SUCCESS();
glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(testpoint, testpoint, GLColor::magenta);
// Make current with null to ensure the Surface can be released immediately.
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(display, pbuffer);
}
// Test creating a pbuffer from a multisampled d3d surface and drawing with a program.
TEST_P(D3DTextureTestMS, DrawProgram)
{
EGLWindow *window = getEGLWindow();
EGLDisplay display = window->getDisplay();
constexpr size_t bufferSize = 32;
EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4,
static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
ASSERT_EGL_SUCCESS();
ASSERT_NE(pbuffer, EGL_NO_SURFACE);
// Apply the Pbuffer and clear it to magenta
eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
ASSERT_EGL_SUCCESS();
glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR();
constexpr GLint testPoint = bufferSize / 2;
EXPECT_PIXEL_COLOR_EQ(testPoint, testPoint, GLColor::magenta);
// Apply the window surface
eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext());
ASSERT_EGL_SUCCESS();
glViewport(0, 0, getWindowWidth(), getWindowHeight());
ASSERT_EGL_SUCCESS();
// Draw a quad and verify that it is magenta
glUseProgram(mTextureProgramNoSampling);
EXPECT_GL_NO_ERROR();
drawQuad(mTextureProgramNoSampling, "position", 0.5f);
EXPECT_GL_NO_ERROR();
// Verify that magenta was drawn
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::magenta);
// Make current with null to ensure the Surface can be released immediately.
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(display, pbuffer);
}
// Test for failure when creating a pbuffer from a multisampled d3d surface to bind to a texture.
TEST_P(D3DTextureTestMS, BindTexture)
{
constexpr size_t bufferSize = 32;
EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 4,
static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
EXPECT_EQ(pbuffer, nullptr);
}
// Verify that creating a pbuffer from a multisampled texture with a multisampled window will fail
// when the sample counts do not match.
TEST_P(D3DTextureTestMS, CheckSampleMismatch)
{
constexpr size_t bufferSize = 32;
EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 2,
static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN));
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
EXPECT_EQ(pbuffer, nullptr);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(D3DTextureTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL()); ANGLE_INSTANTIATE_TEST(D3DTextureTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
ANGLE_INSTANTIATE_TEST(D3DTextureTestMS, ES2_D3D11());
} // namespace } // namespace
...@@ -29,6 +29,7 @@ const GLColor GLColor::red = GLColor(255u, 0u, 0u, 255u); ...@@ -29,6 +29,7 @@ const GLColor GLColor::red = GLColor(255u, 0u, 0u, 255u);
const GLColor GLColor::transparentBlack = GLColor(0u, 0u, 0u, 0u); const GLColor GLColor::transparentBlack = GLColor(0u, 0u, 0u, 0u);
const GLColor GLColor::white = GLColor(255u, 255u, 255u, 255u); const GLColor GLColor::white = GLColor(255u, 255u, 255u, 255u);
const GLColor GLColor::yellow = GLColor(255u, 255u, 0, 255u); const GLColor GLColor::yellow = GLColor(255u, 255u, 0, 255u);
const GLColor GLColor::magenta = GLColor(255u, 0u, 255u, 255u);
namespace namespace
{ {
...@@ -682,6 +683,11 @@ void ANGLETest::setMultisampleEnabled(bool enabled) ...@@ -682,6 +683,11 @@ void ANGLETest::setMultisampleEnabled(bool enabled)
mEGLWindow->setMultisample(enabled); mEGLWindow->setMultisample(enabled);
} }
void ANGLETest::setSamples(EGLint samples)
{
mEGLWindow->setSamples(samples);
}
void ANGLETest::setDebugEnabled(bool enabled) void ANGLETest::setDebugEnabled(bool enabled)
{ {
mEGLWindow->setDebugEnabled(enabled); mEGLWindow->setDebugEnabled(enabled);
......
...@@ -87,6 +87,7 @@ struct GLColor ...@@ -87,6 +87,7 @@ struct GLColor
static const GLColor transparentBlack; static const GLColor transparentBlack;
static const GLColor white; static const GLColor white;
static const GLColor yellow; static const GLColor yellow;
static const GLColor magenta;
}; };
struct GLColor32F struct GLColor32F
...@@ -235,6 +236,7 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters> ...@@ -235,6 +236,7 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
void setConfigStencilBits(int bits); void setConfigStencilBits(int bits);
void setConfigComponentType(EGLenum componentType); void setConfigComponentType(EGLenum componentType);
void setMultisampleEnabled(bool enabled); void setMultisampleEnabled(bool enabled);
void setSamples(EGLint samples);
void setDebugEnabled(bool enabled); void setDebugEnabled(bool enabled);
void setNoErrorEnabled(bool enabled); void setNoErrorEnabled(bool enabled);
void setWebGLCompatibilityEnabled(bool webglCompatibility); void setWebGLCompatibilityEnabled(bool webglCompatibility);
......
...@@ -117,7 +117,8 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion, ...@@ -117,7 +117,8 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion,
mBindGeneratesResource(true), mBindGeneratesResource(true),
mClientArraysEnabled(true), mClientArraysEnabled(true),
mRobustResourceInit(false), mRobustResourceInit(false),
mSwapInterval(-1) mSwapInterval(-1),
mSamples(-1)
{ {
} }
...@@ -228,6 +229,7 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow) ...@@ -228,6 +229,7 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow)
EGL_DEPTH_SIZE, (mDepthBits >= 0) ? mDepthBits : EGL_DONT_CARE, EGL_DEPTH_SIZE, (mDepthBits >= 0) ? mDepthBits : EGL_DONT_CARE,
EGL_STENCIL_SIZE, (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE, EGL_STENCIL_SIZE, (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE,
EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0, EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0,
EGL_SAMPLES, (mSamples >= 0) ? mSamples : EGL_DONT_CARE,
}; };
// Add dynamic attributes // Add dynamic attributes
...@@ -258,6 +260,7 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow) ...@@ -258,6 +260,7 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow)
eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mAlphaBits); eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mAlphaBits);
eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits); eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits);
eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits); eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits);
eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mSamples);
std::vector<EGLint> surfaceAttributes; std::vector<EGLint> surfaceAttributes;
if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr) if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr)
......
...@@ -68,6 +68,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable ...@@ -68,6 +68,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
void setConfigStencilBits(int bits) { mStencilBits = bits; } void setConfigStencilBits(int bits) { mStencilBits = bits; }
void setConfigComponentType(EGLenum componentType) { mComponentType = componentType; } void setConfigComponentType(EGLenum componentType) { mComponentType = componentType; }
void setMultisample(bool multisample) { mMultisample = multisample; } void setMultisample(bool multisample) { mMultisample = multisample; }
void setSamples(EGLint samples) { mSamples = samples; }
void setDebugEnabled(bool debug) { mDebug = debug; } void setDebugEnabled(bool debug) { mDebug = debug; }
void setNoErrorEnabled(bool noError) { mNoError = noError; } void setNoErrorEnabled(bool noError) { mNoError = noError; }
void setWebGLCompatibilityEnabled(bool webglCompatibility) void setWebGLCompatibilityEnabled(bool webglCompatibility)
...@@ -142,6 +143,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable ...@@ -142,6 +143,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable
bool mClientArraysEnabled; bool mClientArraysEnabled;
bool mRobustResourceInit; bool mRobustResourceInit;
EGLint mSwapInterval; EGLint mSwapInterval;
EGLint mSamples;
Optional<bool> mVulkanLayersEnabled; Optional<bool> mVulkanLayersEnabled;
}; };
......
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