Warning, /graphics/krita/3rdparty/ext_googleangle/02-patches_krita/0015-Implement-openGL-surface-color-space-selection-in-An.patch is written in an unsupported language. File is not indexed.

0001 From 0fb8bddb74a58b51bad12a6188f24d13cba2c7f4 Mon Sep 17 00:00:00 2001
0002 From: Dmitry Kazakov <dimula73@gmail.com>
0003 Date: Sat, 8 Dec 2018 15:35:43 +0300
0004 Subject: [PATCH 15/17] Implement openGL surface color space selection in Angle
0005 
0006 WARNING: this patch actually means that the library must be build on
0007          the system with at least DXGI 1.4 (DirectX 12 API) present
0008          in SDK. Mingw64 7.3 supports that.
0009 
0010 1) D3D11 implementation of angle now supports GL_RGB10_A2 format
0011 
0012 2) Technically, Angle's EGL implementation now supports the following
0013    display extensions:
0014      * EGL_KHR_gl_colorspace
0015      * EGL_EXT_gl_colorspace_scrgb_linear
0016      * EGL_EXT_gl_colorspace_bt2020_pq
0017 
0018 3) D3D11 implementation of angle now supports GL_COLOR_SPACE attribute,
0019    which allows selection one of four color modes:
0020      * Linear --- just pass-through data to GPU
0021      * sRGB --- p709-g22 color space. WARNING: in 8-bit mode the system
0022        becomes clever and automatically converts linear framebuffer
0023        attachments to sRGB space, as per EGL_KHR_gl_colorspace definition.
0024        It is not possible to select sRGB without this extra "feature".
0025      * scRGB --- p709-g10 color space. This mode is the only mode
0026        supported in f16-bit mode (and it is also not supported in other
0027        bit depths).
0028      * bt2020-pq --- p2020-pq color space. Supported only in 10-bit mode.
0029 
0030 5) SwapChain is now created in DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL mode:
0031      * because non-flip mode is considered deprecated and HDR is not
0032        supported in it;
0033      * because in flip-discard mode partial updates from
0034        SwapChain11::present() are not supported and return an error,
0035        which is never checked :)
0036 
0037 6) As a fallback, SwapChain uses old DXGI_SWAP_EFFECT_DISCARD, because
0038    flip modes are not available on Windows 7 and such old systems.
0039 
0040 Notes:
0041 
0042 eglCreatePixmapSurface() is not implemented in Angle, so the support is
0043 not added.
0044 
0045 eglCreatePlatformWindowSurface() and eglCreatePlatformPixmapSurface()
0046 do not have support for color spaces according to the extension wording
0047 (and they are also not supported by Angle :) )
0048 
0049 Change-Id: I68204a5db6bbd7066a83a8d1d021ce76cd1cf6f6
0050 ---
0051  src/libANGLE/Caps.cpp                         |  1 +
0052  src/libANGLE/Caps.h                           |  3 +
0053  src/libANGLE/formatutils.h                    |  1 +
0054  src/libANGLE/renderer/d3d/RendererD3D.h       |  3 +-
0055  src/libANGLE/renderer/d3d/SurfaceD3D.cpp      | 26 +++++-
0056  src/libANGLE/renderer/d3d/SurfaceD3D.h        |  1 +
0057  .../renderer/d3d/d3d11/Renderer11.cpp         | 16 +++-
0058  src/libANGLE/renderer/d3d/d3d11/Renderer11.h  |  4 +-
0059  .../renderer/d3d/d3d11/SwapChain11.cpp        | 90 ++++++++++++++++++-
0060  src/libANGLE/renderer/d3d/d3d11/SwapChain11.h |  4 +-
0061  .../d3d/d3d11/win32/NativeWindow11Win32.cpp   | 19 +++-
0062  src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp  |  4 +-
0063  src/libANGLE/renderer/d3d/d3d9/Renderer9.h    |  3 +-
0064  src/libANGLE/validationEGL.cpp                |  8 ++
0065  14 files changed, 170 insertions(+), 13 deletions(-)
0066 
0067 diff --git a/src/libANGLE/Caps.cpp b/src/libANGLE/Caps.cpp
0068 index f4c1beed2..a6e80b102 100644
0069 --- a/src/libANGLE/Caps.cpp
0070 +++ b/src/libANGLE/Caps.cpp
0071 @@ -1245,6 +1245,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
0072      InsertExtensionString("EGL_EXT_gl_colorspace_display_p3",                    glColorspaceDisplayP3,              &extensionStrings);
0073      InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_linear",             glColorspaceDisplayP3Linear,        &extensionStrings);
0074      InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_passthrough",        glColorspaceDisplayP3Passthrough,   &extensionStrings);
0075 +    InsertExtensionString("EGL_EXT_gl_colorspace_bt2020_pq",                     glColorspaceBt2020PQ,               &extensionStrings);
0076      InsertExtensionString("EGL_KHR_gl_texture_2D_image",                         glTexture2DImage,                   &extensionStrings);
0077      InsertExtensionString("EGL_KHR_gl_texture_cubemap_image",                    glTextureCubemapImage,              &extensionStrings);
0078      InsertExtensionString("EGL_KHR_gl_texture_3D_image",                         glTexture3DImage,                   &extensionStrings);
0079 diff --git a/src/libANGLE/Caps.h b/src/libANGLE/Caps.h
0080 index 13429ac2d..c104491f6 100644
0081 --- a/src/libANGLE/Caps.h
0082 +++ b/src/libANGLE/Caps.h
0083 @@ -602,6 +602,9 @@ struct DisplayExtensions
0084      // EGL_EXT_gl_colorspace_display_p3_passthrough
0085      bool glColorspaceDisplayP3Passthrough = false;
0086  
0087 +    // EGL_EXT_gl_colorspace_bt2020_pq
0088 +    bool glColorspaceBt2020PQ = false;
0089 +
0090      // EGL_ANDROID_framebuffer_target
0091      bool framebufferTargetANDROID = false;
0092  
0093 diff --git a/src/libANGLE/formatutils.h b/src/libANGLE/formatutils.h
0094 index c53a25151..cd411bae8 100644
0095 --- a/src/libANGLE/formatutils.h
0096 +++ b/src/libANGLE/formatutils.h
0097 @@ -87,6 +87,7 @@ ANGLE_INLINE bool ColorspaceFormatOverride(const EGLenum colorspace, GLenum *ren
0098          case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:  // App, not the HW, will specify the
0099                                                              // transfer function
0100          case EGL_GL_COLORSPACE_SCRGB_EXT:  // App, not the HW, will specify the transfer function
0101 +        case EGL_GL_COLORSPACE_BT2020_PQ_EXT: // App, not the HW, will specify the transfer function
0102              // No translation
0103              return true;
0104          case EGL_GL_COLORSPACE_SRGB_KHR:
0105 diff --git a/src/libANGLE/renderer/d3d/RendererD3D.h b/src/libANGLE/renderer/d3d/RendererD3D.h
0106 index d681e5b7e..f2874242e 100644
0107 --- a/src/libANGLE/renderer/d3d/RendererD3D.h
0108 +++ b/src/libANGLE/renderer/d3d/RendererD3D.h
0109 @@ -182,7 +182,8 @@ class RendererD3D : public BufferFactoryD3D
0110                                            GLenum backBufferFormat,
0111                                            GLenum depthBufferFormat,
0112                                            EGLint orientation,
0113 -                                          EGLint samples)                          = 0;
0114 +                                          EGLint samples,
0115 +                                          EGLint colorSpace)                       = 0;
0116      virtual egl::Error getD3DTextureInfo(const egl::Config *configuration,
0117                                           IUnknown *d3dTexture,
0118                                           const egl::AttributeMap &attribs,
0119 diff --git a/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
0120 index 6fc42139a..a9950ab14 100644
0121 --- a/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
0122 +++ b/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
0123 @@ -24,6 +24,27 @@
0124  namespace rx
0125  {
0126  
0127 +GLenum renderTargetFormatFromColorSpace(egl::Display *display, GLenum baseFormat, EGLint colorSpace)
0128 +{
0129 +    GLenum result = baseFormat;
0130 +
0131 +    /**
0132 +     * If sRGB extension is supported, we should change the surface format
0133 +     * to a specific one that does support automated gamma conversion.
0134 +     *
0135 +     * TODO: openGL doesn't support BGRA-sRGB texture format, so creation of
0136 +     *       textures in this format technically is not supported!
0137 +     */
0138 +    if (display->getExtensions().glColorspace &&
0139 +        baseFormat == GL_RGBA8_OES &&
0140 +        colorSpace == EGL_GL_COLORSPACE_SRGB_KHR)
0141 +    {
0142 +        result = GL_SRGB8_ALPHA8;
0143 +    }
0144 +
0145 +    return result;
0146 +}
0147 +
0148  SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
0149                         RendererD3D *renderer,
0150                         egl::Display *display,
0151 @@ -38,7 +59,8 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
0152        mFixedWidth(0),
0153        mFixedHeight(0),
0154        mOrientation(static_cast<EGLint>(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0))),
0155 -      mRenderTargetFormat(state.config->renderTargetFormat),
0156 +      mColorSpace(static_cast<EGLint>(attribs.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR))),
0157 +      mRenderTargetFormat(renderTargetFormatFromColorSpace(display, state.config->renderTargetFormat, mColorSpace)),
0158        mDepthStencilFormat(state.config->depthStencilFormat),
0159        mColorFormat(nullptr),
0160        mSwapChain(nullptr),
0161 @@ -203,7 +225,7 @@ egl::Error SurfaceD3D::resetSwapChain(const egl::Display *display)
0162  
0163      mSwapChain =
0164          mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture, mRenderTargetFormat,
0165 -                                   mDepthStencilFormat, mOrientation, mState.config->samples);
0166 +                                   mDepthStencilFormat, mOrientation, mState.config->samples, mColorSpace);
0167      if (!mSwapChain)
0168      {
0169          return egl::EglBadAlloc();
0170 diff --git a/src/libANGLE/renderer/d3d/SurfaceD3D.h b/src/libANGLE/renderer/d3d/SurfaceD3D.h
0171 index c48c8eb49..f0ecb67e7 100644
0172 --- a/src/libANGLE/renderer/d3d/SurfaceD3D.h
0173 +++ b/src/libANGLE/renderer/d3d/SurfaceD3D.h
0174 @@ -93,6 +93,7 @@ class SurfaceD3D : public SurfaceImpl
0175      GLint mFixedWidth;
0176      GLint mFixedHeight;
0177      GLint mOrientation;
0178 +    EGLint mColorSpace;
0179  
0180      GLenum mRenderTargetFormat;
0181      GLenum mDepthStencilFormat;
0182 diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
0183 index e89719966..c340b4971 100644
0184 --- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
0185 +++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
0186 @@ -429,6 +429,7 @@ Renderer11::Renderer11(egl::Display *display)
0187      mRenderer11DeviceCaps.supportsConstantBufferOffsets          = false;
0188      mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader = false;
0189      mRenderer11DeviceCaps.supportsDXGI1_2                        = false;
0190 +    mRenderer11DeviceCaps.supportsDXGI1_4                        = false;
0191      mRenderer11DeviceCaps.allowES3OnFL10_0                       = false;
0192      mRenderer11DeviceCaps.B5G6R5support                          = 0;
0193      mRenderer11DeviceCaps.B4G4R4A4support                        = 0;
0194 @@ -1024,6 +1025,7 @@ egl::Error Renderer11::initializeDevice()
0195  
0196      // Gather stats on DXGI and D3D feature level
0197      ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.SupportsDXGI1_2", mRenderer11DeviceCaps.supportsDXGI1_2);
0198 +    ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.SupportsDXGI1_4", mRenderer11DeviceCaps.supportsDXGI1_4);
0199  
0200      ANGLEFeatureLevel angleFeatureLevel = GetANGLEFeatureLevel(mRenderer11DeviceCaps.featureLevel);
0201  
0202 @@ -1113,6 +1115,10 @@ void Renderer11::populateRenderer11DeviceCaps()
0203      IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
0204      mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr);
0205      SafeRelease(dxgiAdapter2);
0206 +
0207 +    IDXGIAdapter3 *dxgiAdapter3 = d3d11::DynamicCastComObject<IDXGIAdapter3>(mDxgiAdapter);
0208 +    mRenderer11DeviceCaps.supportsDXGI1_4 = (dxgiAdapter3 != nullptr);
0209 +    SafeRelease(dxgiAdapter3);
0210  }
0211  
0212  gl::SupportedSampleSet Renderer11::generateSampleSetForEGLConfig(
0213 @@ -1358,6 +1364,11 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions
0214          outExtensions->windowsUIComposition = true;
0215      }
0216  #endif
0217 +
0218 +    // color space selection supported in DXGI 1.4 only
0219 +    outExtensions->glColorspace = mRenderer11DeviceCaps.supportsDXGI1_4;
0220 +    outExtensions->glColorspaceScrgbLinear = mRenderer11DeviceCaps.supportsDXGI1_4;
0221 +    outExtensions->glColorspaceBt2020PQ = mRenderer11DeviceCaps.supportsDXGI1_4;
0222  }
0223  
0224  angle::Result Renderer11::flush(Context11 *context11)
0225 @@ -1708,10 +1719,11 @@ SwapChainD3D *Renderer11::createSwapChain(NativeWindowD3D *nativeWindow,
0226                                            GLenum backBufferFormat,
0227                                            GLenum depthBufferFormat,
0228                                            EGLint orientation,
0229 -                                          EGLint samples)
0230 +                                          EGLint samples,
0231 +                                          EGLint colorSpace)
0232  {
0233      return new SwapChain11(this, GetAs<NativeWindow11>(nativeWindow), shareHandle, d3dTexture,
0234 -                           backBufferFormat, depthBufferFormat, orientation, samples);
0235 +                           backBufferFormat, depthBufferFormat, orientation, samples, colorSpace);
0236  }
0237  
0238  void *Renderer11::getD3DDevice()
0239 diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
0240 index 04821c43a..9d8d8fdfd 100644
0241 --- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
0242 +++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
0243 @@ -49,6 +49,7 @@ struct Renderer11DeviceCaps
0244  
0245      D3D_FEATURE_LEVEL featureLevel;
0246      bool supportsDXGI1_2;                         // Support for DXGI 1.2
0247 +    bool supportsDXGI1_4;                         // Support for DXGI 1.4
0248      bool supportsClearView;                       // Support for ID3D11DeviceContext1::ClearView
0249      bool supportsConstantBufferOffsets;           // Support for Constant buffer offset
0250      bool supportsVpRtIndexWriteFromVertexShader;  // VP/RT can be selected in the Vertex Shader
0251 @@ -101,7 +102,8 @@ class Renderer11 : public RendererD3D
0252                                    GLenum backBufferFormat,
0253                                    GLenum depthBufferFormat,
0254                                    EGLint orientation,
0255 -                                  EGLint samples) override;
0256 +                                  EGLint samples,
0257 +                                  EGLint colorSpace) override;
0258      egl::Error getD3DTextureInfo(const egl::Config *configuration,
0259                                   IUnknown *d3dTexture,
0260                                   const egl::AttributeMap &attribs,
0261 diff --git a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
0262 index a82b77b33..c69d84eb5 100644
0263 --- a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
0264 +++ b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
0265 @@ -19,6 +19,11 @@
0266  #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
0267  #include "libANGLE/trace.h"
0268  
0269 +#if 0
0270 +// used only for HDR metadata configuration options
0271 +#include <dxgi1_5.h>
0272 +#endif
0273 +
0274  // Precompiled shaders
0275  #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
0276  #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
0277 @@ -58,12 +63,14 @@ SwapChain11::SwapChain11(Renderer11 *renderer,
0278                           GLenum backBufferFormat,
0279                           GLenum depthBufferFormat,
0280                           EGLint orientation,
0281 -                         EGLint samples)
0282 +                         EGLint samples,
0283 +                         EGLint colorSpace)
0284      : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat),
0285        mRenderer(renderer),
0286        mWidth(-1),
0287        mHeight(-1),
0288        mOrientation(orientation),
0289 +      mColorSpace(colorSpace),
0290        mAppCreatedShareHandle(mShareHandle != nullptr),
0291        mSwapInterval(0),
0292        mPassThroughResourcesInit(false),
0293 @@ -655,10 +662,91 @@ EGLint SwapChain11::reset(DisplayD3D *displayD3D,
0294              mSwapChain1 = d3d11::DynamicCastComObject<IDXGISwapChain1>(mSwapChain);
0295          }
0296  
0297 +        if (mRenderer->getRenderer11DeviceCaps().supportsDXGI1_4)
0298 +        {
0299 +            IDXGISwapChain3 *swapChain3 = d3d11::DynamicCastComObject<IDXGISwapChain3>(mSwapChain);
0300 +
0301 +            // printf("*** EGL colorSpace: 0x%X\n", mColorSpace);
0302 +            // printf("*** EGL format: 0x%X\n", mOffscreenRenderTargetFormat);
0303 +            // printf("*** Native format: 0x%X\n", getSwapChainNativeFormat());
0304 +
0305 +            if (mColorSpace != EGL_GL_COLORSPACE_LINEAR_KHR) {
0306 +                DXGI_COLOR_SPACE_TYPE nativeColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
0307 +                switch (mColorSpace)
0308 +                {
0309 +                case EGL_GL_COLORSPACE_SRGB_KHR:
0310 +                    nativeColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
0311 +                    break;
0312 +                case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
0313 +                    nativeColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
0314 +                    break;
0315 +                case EGL_GL_COLORSPACE_BT2020_PQ_EXT:
0316 +                    nativeColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
0317 +                    break;
0318 +                default:
0319 +                    ASSERT(0 && "Unsupported colorspace requested");
0320 +                }
0321 +
0322 +                // printf("*** Native colorSpace: 0x%X\n", nativeColorSpace);
0323 +
0324 +                UINT supported = 0;
0325 +                hr = swapChain3->CheckColorSpaceSupport(nativeColorSpace, &supported);
0326 +                ASSERT(SUCCEEDED(hr));
0327 +                if (!(supported & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT)) {
0328 +                    SafeRelease(swapChain3);
0329 +                    return EGL_BAD_MATCH;
0330 +                }
0331 +
0332 +                hr = swapChain3->SetColorSpace1(nativeColorSpace);
0333 +                ASSERT(SUCCEEDED(hr));
0334 +            }
0335 +
0336 +            SafeRelease(swapChain3);
0337 +
0338 +#if 0
0339 +
0340 +            IDXGISwapChain4 *swapChain4 = d3d11::DynamicCastComObject<IDXGISwapChain4>(mSwapChain);
0341 +
0342 +            DXGI_HDR_METADATA_HDR10 md;
0343 +            md.RedPrimary[0] = 0.680 * 50000;
0344 +            md.RedPrimary[1] = 0.320 * 50000;
0345 +            md.GreenPrimary[0] = 0.265 * 50000;
0346 +            md.GreenPrimary[1] = 0.690 * 50000;
0347 +            md.BluePrimary[0] = 0.150 * 50000;
0348 +            md.BluePrimary[1] = 0.060 * 50000;
0349 +            md.WhitePoint[0] = 0.3127 * 50000;
0350 +            md.WhitePoint[1] = 0.3290 * 50000;
0351 +            md.MaxMasteringLuminance = 1000 * 10000;
0352 +            md.MinMasteringLuminance = 0.001 * 10000;
0353 +            md.MaxContentLightLevel = 1000;
0354 +            md.MaxFrameAverageLightLevel = 200;
0355 +            result = swapChain4->SetHDRMetaData(DXGI_HDR_METADATA_TYPE_HDR10, sizeof(md), &md);
0356 +            // printf("*** Result hdr 0x%X\n", result);
0357 +            SafeRelease(swapChain4);
0358 +#endif
0359 +        }
0360 +
0361          ID3D11Texture2D *backbufferTex = nullptr;
0362          hr                             = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
0363                                     reinterpret_cast<LPVOID *>(&backbufferTex));
0364          ASSERT(SUCCEEDED(hr));
0365 +
0366 +        // TODO: recover rendering to sRGB
0367 +        //
0368 +        // D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
0369 +        // offscreenRTVDesc.Format = getSwapChainNativeFormat();
0370 +        //
0371 +        // if (mColorSpace == EGL_GL_COLORSPACE_SRGB_KHR) {
0372 +        //     if (offscreenRTVDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM) {
0373 +        //         offscreenRTVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
0374 +        //     }
0375 +        //
0376 +        //     if (offscreenRTVDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM) {
0377 +        //         offscreenRTVDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
0378 +        //     }
0379 +        // }
0380 +        //
0381 +        // printf("*** Render target format: 0x%X\n", offscreenRTVDesc.Format);
0382          const auto &format =
0383              d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
0384          mBackBufferTexture.set(backbufferTex, format);
0385 diff --git a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
0386 index 9dd98462c..a42a941c2 100644
0387 --- a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
0388 +++ b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
0389 @@ -28,7 +28,8 @@ class SwapChain11 final : public SwapChainD3D
0390                  GLenum backBufferFormat,
0391                  GLenum depthBufferFormat,
0392                  EGLint orientation,
0393 -                EGLint samples);
0394 +                EGLint samples,
0395 +                EGLint colorSpace);
0396      ~SwapChain11() override;
0397  
0398      EGLint resize(DisplayD3D *displayD3D, EGLint backbufferWidth, EGLint backbufferHeight) override;
0399 @@ -91,6 +92,7 @@ class SwapChain11 final : public SwapChainD3D
0400      EGLint mWidth;
0401      EGLint mHeight;
0402      const EGLint mOrientation;
0403 +    EGLint mColorSpace;
0404      bool mAppCreatedShareHandle;
0405      unsigned int mSwapInterval;
0406      bool mPassThroughResourcesInit;
0407 diff --git a/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp b/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp
0408 index 722510a48..10462a970 100644
0409 --- a/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp
0410 +++ b/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp
0411 @@ -147,6 +147,9 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device,
0412  
0413      // Use IDXGIFactory2::CreateSwapChainForHwnd if DXGI 1.2 is available to create a
0414      // DXGI_SWAP_EFFECT_SEQUENTIAL swap chain.
0415 +    //
0416 +    // NOTE: in non-flip mode HDR rendering is not supported, so use it
0417 +    //       by default
0418      IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject<IDXGIFactory2>(factory);
0419      if (factory2 != nullptr)
0420      {
0421 @@ -159,9 +162,9 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device,
0422          swapChainDesc.SampleDesc.Quality    = 0;
0423          swapChainDesc.BufferUsage =
0424              DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
0425 -        swapChainDesc.BufferCount   = 1;
0426 +        swapChainDesc.BufferCount   = 2;
0427          swapChainDesc.Scaling       = DXGI_SCALING_STRETCH;
0428 -        swapChainDesc.SwapEffect    = DXGI_SWAP_EFFECT_SEQUENTIAL;
0429 +        swapChainDesc.SwapEffect    = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
0430          swapChainDesc.AlphaMode     = DXGI_ALPHA_MODE_UNSPECIFIED;
0431          swapChainDesc.Flags         = 0;
0432          IDXGISwapChain1 *swapChain1 = nullptr;
0433 @@ -177,7 +180,7 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device,
0434      }
0435  
0436      DXGI_SWAP_CHAIN_DESC swapChainDesc               = {};
0437 -    swapChainDesc.BufferCount                        = 1;
0438 +    swapChainDesc.BufferCount                        = 2;
0439      swapChainDesc.BufferDesc.Format                  = format;
0440      swapChainDesc.BufferDesc.Width                   = width;
0441      swapChainDesc.BufferDesc.Height                  = height;
0442 @@ -192,6 +195,16 @@ HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device,
0443      swapChainDesc.SampleDesc.Count   = samples;
0444      swapChainDesc.SampleDesc.Quality = 0;
0445      swapChainDesc.Windowed           = TRUE;
0446 +
0447 +    /**
0448 +     * NOTE1: in discard mode the swap chain doesn't support partial
0449 +     *        presentatiopn with Present1() call. Though it is not a big
0450 +     *        problem, because in case DXGI 1.2 is supported this code is
0451 +     *        unreachable.
0452 +     *
0453 +     * NOTE2: Flip modes are not supported on Windows 7 and the like,
0454 +     *        so use a legacy mode as a fallback
0455 +     */
0456      swapChainDesc.SwapEffect         = DXGI_SWAP_EFFECT_DISCARD;
0457  
0458      HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, swapChain);
0459 diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
0460 index 42932bd84..19f43422d 100644
0461 --- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
0462 +++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
0463 @@ -721,8 +721,10 @@ SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow,
0464                                           GLenum backBufferFormat,
0465                                           GLenum depthBufferFormat,
0466                                           EGLint orientation,
0467 -                                         EGLint samples)
0468 +                                         EGLint samples,
0469 +                                         EGLint colorSpace)
0470  {
0471 +    ANGLE_UNUSED_VARIABLE(colorSpace);
0472      return new SwapChain9(this, GetAs<NativeWindow9>(nativeWindow), shareHandle, d3dTexture,
0473                            backBufferFormat, depthBufferFormat, orientation);
0474  }
0475 diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
0476 index 8a306a026..bd0fd4932 100644
0477 --- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
0478 +++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
0479 @@ -73,7 +73,8 @@ class Renderer9 : public RendererD3D
0480                                    GLenum backBufferFormat,
0481                                    GLenum depthBufferFormat,
0482                                    EGLint orientation,
0483 -                                  EGLint samples) override;
0484 +                                  EGLint samples,
0485 +                                  EGLint colorSpace) override;
0486      egl::Error getD3DTextureInfo(const egl::Config *configuration,
0487                                   IUnknown *d3dTexture,
0488                                   const egl::AttributeMap &attribs,
0489 diff --git a/src/libANGLE/validationEGL.cpp b/src/libANGLE/validationEGL.cpp
0490 index 472405d5b..d897beb34 100644
0491 --- a/src/libANGLE/validationEGL.cpp
0492 +++ b/src/libANGLE/validationEGL.cpp
0493 @@ -461,6 +461,14 @@ bool ValidateColorspaceAttribute(const ValidationContext *val,
0494                  return false;
0495              }
0496              break;
0497 +        case EGL_GL_COLORSPACE_BT2020_PQ_EXT:
0498 +            if (!displayExtensions.glColorspaceBt2020PQ)
0499 +            {
0500 +                val->setError(EGL_BAD_ATTRIBUTE,
0501 +                              "EGL_EXT_gl_colorspace_bt2020_pq is not available.");
0502 +                return false;
0503 +            }
0504 +            break;
0505          default:
0506              val->setError(EGL_BAD_ATTRIBUTE);
0507              return false;
0508 -- 
0509 2.24.1.windows.2
0510